pythonで2d CADファイル「.dxf」を作成[ezdxf]

## .dxf??

CAD(機械などの設計図を描くソフト)では様々なファイル形式が使われています。「.dxf」はその内の1つです。

他にもファイル形式はありますが、よく使われる「.dwg」であればAuto CAD等の特定のソフトでしか読み込むことができません。

一方「.dxf」は仕様が公開されているため、特定のソフトだけではなく、様々なソフトで読み込み、書き込みが可能です。(テキストエディタで開くと中身が読めます。)

そのため様々な企業間で図面のやり取りで使う、業界標準みたいなファイル形式なっています(多分…)。

## ezdxf??
pythonでdxfファイルを作成したり、読み込んだりしてくれるライブラリです。
https://ezdxf.readthedocs.io/en/stable/

例えばAutoCAD(結構高価)を使えば、VBAを使って自動作画のプログラムが作れたりします。
https://www.youtube.com/watch?v=cL7vAIFjsmQ
AutoCADがあるなら、こちらのほうが便利な場合も多いでしょう。

しかしながら
pythonを使ってCADの自動作画したい,AutoCADを持っていなくてもCADの自動作画したい、そんな需要も中にはあるでしょう…(たぶん)。
そんなときに使えるのが「ezdxf」です。


インストールはAnacondaにもあるので簡単!
conda install -c conda-forge ezdxf


## 直線を描いてみる

ezdxfを使って、直線を描いて保存してみます(チュートリアルそのままですが)。
実質5行の命令文で.dxfファイルが作成できます。

```python
#python 3.85
import ezdxf #'0.13.1'

#dxfのversion指定
doc = ezdxf.new("R2010")

#モデル空間に新しいエンティティを作成
msp = doc.modelspace() 

#直線を作成
msp.add_line(start=[0, 0], end=[100, 0])

#保存
doc.saveas('line.dxf')
```

作成した.dxfファイルを開くとこのような一本の直線ができています(寂しい)。
![line.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141993/7dd3354f-c6dc-c096-4923-81f58453c287.png)

余談ですが
最初、普及率の高い無料CADのjwcadをダウンロードしてみたんですが、
使い方が全く分からなかったので（図形動かねーんだけど!)、
このCADファイルはLibre Office Drawで開きました。

使い慣れたらjwcadは素晴らしいCADらしいですが、操作方法が他のCADと違うみたいで、
他のCADを使っていた人がそのままの感覚で使うと、ハマルポイントがあるらしいです。
(jwcadの勉強が面倒なので、手抜き)

他にも無料のCADはあるらしいので、
普段、有償のCAD業務で使っている人がお家で遊ぶ分には、
他のCADを試すのもよいかもしれません。



1本の線だと流石にアレなので、もう少し線の数を増やして四角形を作ってみます。

```python
import ezdxf #'0.13.1'
doc = ezdxf.new("R2010")  #dxfのversion指定

msp = doc.modelspace() #add new entities to the modelspace
msp.add_line([0, 0], [100, 0])
msp.add_line([100, 0], [100, 100])
msp.add_line([100, 100], [0, 100])
msp.add_line([0, 100], [0, 0])
doc.saveas('tetra.dxf')  #保存
```

作成したファイルを開いてみます。

![shikaku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141993/10a0cb58-1143-3341-25e4-629f7bc1962b.png)

ちゃんと四角形が作図できました。





## 画層の設定

.dxf等の2d CADでは画層(レイヤー)の設定を考える必要があります。
画層とは、同じ線種の集まりで、画層毎に線種(ドットなど)や色などが異なります。

画層を事前に定義し、直線や円を描く際に画層を指定します(引数:dxfattribs)。

```python
import ezdxf #'0.13.1'
#dxfでversion指定
doc = ezdxf.new("R2010", setup=True)

#画層の定義
doc.layers.new(name="MyLine1", dxfattribs={'linetype': 'DASHED', 'color': 7})
doc.layers.new(name="MyLine2", dxfattribs={'linetype': 'CONTINUOUS', 'color': 1})
doc.layers.new(name="MyLine3", dxfattribs={'linetype': 'CENTER', 'color': 2})

#add new entities to the modelspace
msp = doc.modelspace() 

#直線の追加
msp.add_line([0, 0], [100, 0], dxfattribs={'layer': 'MyLine1'})
msp.add_line([100, 0], [100, 100], dxfattribs={'layer': 'MyLine1'})
msp.add_line([100, 100], [0, 100], dxfattribs={'layer': 'MyLine1'})
msp.add_line([0, 100], [0, 0], dxfattribs={'layer': 'MyLine1'})

#中心[50, 50],半径50の円の追加
msp.add_circle(center=[50, 50], radius=50, dxfattribs={'layer': 'MyLine2'})

#円弧の追加
msp.add_arc(center=[50, 50], radius=40, 
            start_angle=0, end_angle=90, dxfattribs={'layer': 'MyLine2'})
msp.add_arc(center=[50, 50], radius=40,
            start_angle=90, end_angle=360, dxfattribs={'layer': 'MyLine3'})

#[50, 50]の位置に点を追加
msp.add_point([50, 50], dxfattribs={'layer': 'MyLine1'})

#画像の保存
doc.saveas('sample.dxf')

```



作成したファイルを開いくと、以下のようになりました。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141993/5c3de413-6ea4-0d4f-3e35-ef08104343f1.png)

最初、[50, 50]の位置の点が小さすぎて、液晶モニタについたゴミと勘違いしていた。