ezdxfを使ってみよう #1~導入編~【PythonでAutoCAD互換図面(DXF)を自動生成】

当ページのリンクには広告が含まれています。
  • URLをコピーしました!

※本ページはプロモーション(広告)が含まれています。当サイトは各種アフィリエイトプログラムに参加しており、リンク経由で報酬を得る場合があります。詳しくはプライバシーポリシーをご確認ください。

PythonでCADの図面を自動生成できるライブラリ、「ezdxf」についてご紹介致します。
CAD自動作図のために勉強したのですが、公式ライブラリが英語だけで、しかも分かり難い内容でしたので、ここにまとめたいと思います。

本記事は過去Quiitaにて投稿した記事のリライト記事です。

座標や寸法をコードで定義できるので、規格の異なる構造物を同じロジックで量産したり、Excelの数値をそのまま図面に変換したりといった自動化が可能になります。

——本記事はシリーズ第1回として、ezdxfのインストールから、最短5行での作図、そして毎回のフォント・線種設定を省力化する「setup」機能までを解説します。

図形の描画方法・レイヤーや寸法線の設定は第2回、実際の構造物を自動作図する実践編は第3回で解説します。

目次

ezdxfとは

ezdxfは、DXF(AutoCADの図面交換フォーマット)をPythonで読み書きするためのオープンソースライブラリです。AutoCAD互換のDXFファイルをそのまま出力できるため、普段AutoCADで作業している現場にも、Pythonによる作図の自動化をそのまま持ち込めます。

動作確認環境バージョン
OSWindows 11(64bit)
Python3.8.10
ezdxf1.4.4

ezdxfは開発が活発なライブラリです。現在pip installすると上記より新しいバージョンが入りますが、基本的な使い方(本記事の内容)に大きな違いはありません。気になる場合は公式ドキュメントの更新履歴を確認してください。

インストール

pip install ezdxf

Excelに記録した座標を読み込んで作図したり、DXFを読み込んでExcelに図形情報をまとめたりする場合は、openpyxlpandasも併せて使います。この使い方は第3回で扱います。

自動作図は最短5行!

まずは線を1本だけ引いたDXFを作成してみます。
図形の描き方の詳細は第2回で扱うので、ここでは全体の流れをご紹介致します。

import ezdxf
# 新規のdxfを作成してバージョンを定義する
doc = ezdxf.new('R2010')
# モデルスペースを変数に定義する
msp = doc.modelspace()
# モデルスペースに線を挿入
msp.add_line((0, 0), (10, 0))
# dxfを現在のディレクトリに保存
doc.saveas('図面1.dxf')

これで線が1本入ったDXFファイルが作られます。「新規作成 → モデルスペース取得 → 図形を追加 → 保存」という4手順が、ezdxfで作図するときの基本の型になります。

参考:公式ドキュメント(Tutorial for Creating DXF Drawings)

つかだ

この型を基本として、add_lineの部分を色々な図形に差し替えていくだけで作図ができます!

エディタ内でDXFを即確認できる

Pythonで生成したDXFを、確認のたびにCADソフトで開いていては時間がかかります。
matplotlibを使ったezdxfのアドオンで、コードを実行したその場でプレビューできるようにします。

import matplotlib.pyplot as plt
import ezdxf
from ezdxf.addons.drawing import RenderContext, Frontend
from ezdxf.addons.drawing.matplotlib import MatplotlibBackend

doc = ezdxf.new('R2010')
msp = doc.modelspace()
msp.add_line((0, 0), (10, 0))

#プレビュー生成用のコード
fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ctx = RenderContext(doc)
out = MatplotlibBackend(ax)
config = Configuration(background_policy=BackgroundPolicy.BLACK) #背景色の設定
Frontend(ctx, out, config=config).draw_layout(msp, finalize=True)

DXFのデータをグラフとして画像化する仕組みなので、寸法線など一部の要素はうまく表現されないことがあります。あくまで「ざっくり確認用」と捉えてください。

参考:公式ドキュメント(Drawing / Export Add-on)

便利なsetupを設定

新規作成時にsetup=Trueを渡すだけで、フォント・線種・寸法線・表示スタイルの規格一式がプリセットされます。

通常、ezdxfで文字のフォントや線種を使うには、まず個別に登録する作業が必要になります。
毎回これをやるのはかなり面倒でコードも煩雑になります。

つかだ

複数のスタイルを一括セットできる、「setup=True」の活用をオススメします!

# 全部まとめて指定
doc = ezdxf.new("R2010", setup=True)

# 必要なものだけ個別に指定することもできる
doc = ezdxf.new("R2010", setup=['linetypes', 'styles'])

setupでプリセットされる中身は次の4種類です。

項目件数内容
linetypes(線種)21種類Continuous・CENTER・DASHED・DOTなど
styles(フォント)26種類OpenSans系・LiberationSans系・LiberationSerif系など
dimstyles(寸法線)12種類Standard・EZDXF・サイズ別プリセット(EZ_M_100_H25_CMなど)
visualstyles(表示スタイル)25種類3D表示用のスタイル一式

参考:公式ドキュメント(Predefined Resources)

プリセットされるstyles(フォント)はすべて英字フォントです。日本語を表示するには別途フォントの追加登録が必要になります。この手順は第2回で扱います。

setupの中身を確認「linetypes

先ほどの「最短5行」の型に、リストとforループを組み合わせると、プリセットされた内容を一覧表示するDXFを自動作図できます。線種の一覧を例に見てみます。ByBlock(ブロックの設定に従う)・ByLayer(レイヤーの設定に従う)の2つは実線そのものではなく、参照先の設定を引き継ぐ特殊な線種です。

linetypes一覧

ByBlock(ブロックの設定に従う) ・ByLayer(レイヤーの設定に従う) ・Continuous ・CENTER ・CENTERX2 ・CENTER2 ・DASHED ・DASHEDX2 ・DASHED2 ・PHANTOM ・PHANTOMX2 PHANTOM2 ・DASHDOT ・DASHDOTX2 ・DASHDOT2 ・DOT ・DOTX2 ・DOT2 ・DIVIDE ・DIVIDEX2 ・DIVIDE2

linetypes = ['ByBlock', 'ByLayer', 'Continuous', 'CENTER', 'CENTERX2', 'CENTER2', 'DASHED',
             'DASHEDX2', 'DASHED2', 'PHANTOM', 'PHANTOMX2', 'PHANTOM2', 'DASHDOT', 'DASHDOTX2',
             'DASHDOT2', 'DOT', 'DOTX2', 'DOT2', 'DIVIDE', 'DIVIDEX2', 'DIVIDE2']

doc = ezdxf.new("R2010", setup=True)
msp = doc.modelspace()

for i, linetype in enumerate(linetypes):
    msp.add_text(str(i + 1) + " " + linetype,
                 dxfattribs={'layer': 'TEXTLAYER', 'height': 10}).set_pos((0, -20 * i))
    msp.add_line(start=[100, -20 * i + 5], end=[500, -20 * i + 5],
                 dxfattribs={'layer': 'TEXTLAYER', 'linetype': linetype})

図形を1つずつ手で置くのではなく、リストに入れてforループで回す——これがPythonで作図する最大の強みです。同じ考え方は、寸法線(dimstyles)やフォント(styles)の一覧表示にもそのまま使えます。

なお線種の見た目は使用しているCADソフトの設定に依存する場合があります。

setupの中身を確認「styles

同じ考え方で、プリセットされる26種類のフォント名も一覧表示できます。

styles一覧

Standard ・OpenSans-Light ・OpenSans-Light-Italic ・OpenSans ・OpenSans-Italic ・OpenSans-SemiBold ・OpenSans-SemiBoldItalic ・OpenSans-Bold ・OpenSans ・BoldItalic ・OpenSans-ExtraBold ・OpenSans-ExtraBoldItalic ・OpenSansCondensed-Bold ・OpenSansCondensed-Light ・OpenSansCondensed-Italic ・LiberationSans ・LiberationSans-Bold ・LiberationSans-BoldItalic ・LiberationSans-Italic ・LiberationSerif ・LiberationSerif-Bold ・LiberationSerif-BoldItalic ・LiberationSerif-Italic ・LiberationMono ・LiberationMono-Bold ・LiberationMono-BoldItalic ・LiberationMono-Italic

styles = ['Standard', 'OpenSans-Light', 'OpenSans-Light-Italic', 'OpenSans', 'OpenSans-Italic',
          'OpenSans-SemiBold', 'OpenSans-SemiBoldItalic', 'OpenSans-Bold', 'OpenSans-BoldItalic',
          'OpenSans-ExtraBold', 'OpenSans-ExtraBoldItalic', 'OpenSansCondensed-Bold',
          'OpenSansCondensed-Light', 'OpenSansCondensed-Italic', 'LiberationSans',
          'LiberationSans-Bold', 'LiberationSans-BoldItalic', 'LiberationSans-Italic',
          'LiberationSerif', 'LiberationSerif-Bold', 'LiberationSerif-BoldItalic',
          'LiberationSerif-Italic', 'LiberationMono', 'LiberationMono-Bold',
          'LiberationMono-BoldItalic', 'LiberationMono-Italic']

doc = ezdxf.new("R2010", setup=True, units=True)
msp = doc.modelspace()

for i, style in enumerate(styles):
    msp.add_text("style " + str(i + 1) + " " + style,
                 dxfattribs={'layer': 'TEXTLAYER', 'style': style, 'height': 15}).set_pos((0, -20 * i))

一覧の名前が示すとおり、プリセットはOpenSans系Liberation系(Sans/Serif/Mono)の2ファミリーで構成されています。すべて英字フォントで、日本語は表示されません(追加方法は第2回で解説しています)。

参考:公式ドキュメント(Standard Text Styles)

setupの中身を確認「dimstyles

寸法線のプリセットは12種類です。文字や矢印を表示するため、寸法線だけは作成後に.render()を呼ぶ必要があります(詳しくは第2回で解説しています)。

dimstyles一覧

Standard ・EZDXF ・EZ_M_100_H25_CM ・EZ_M_50_H25_CM ・EZ_M_25_H25_CM ・EZ_M_20_H25_CM ・EZ_M_10_H25_CM ・EZ_M_5_H25_CM ・EZ_M_1_H25_CM ・EZ_RADIUS ・EZ_RADIUS_INSIDE ・EZ_CURVED

dimstyles = ['Standard', 'EZDXF', 'EZ_M_100_H25_CM', 'EZ_M_50_H25_CM', 'EZ_M_25_H25_CM',
             'EZ_M_20_H25_CM', 'EZ_M_10_H25_CM', 'EZ_M_5_H25_CM', 'EZ_M_1_H25_CM',
             'EZ_RADIUS', 'EZ_RADIUS_INSIDE', 'EZ_CURVED']

doc = ezdxf.new("R2010", setup=True)
msp = doc.modelspace()

for i, dimstyle in enumerate(dimstyles):
    msp.add_text(str(i + 1) + " " + dimstyle,
                 dxfattribs={'layer': 'TEXTLAYER', 'style': dimstyle, 'height': 0.1}).set_pos((-2, -0.5 * i))
    msp.add_line(start=[0, -0.5 * i + 0.1], end=[1, -0.5 * i + 0.1],
                 dxfattribs={'layer': 'TEXTLAYER'})

    dim = msp.add_linear_dim(
        base=(1, -0.5 * i + 0.1),   # 寸法線の位置
        p1=(0, -0.5 * i + 0.1),      # 1点目
        p2=(1, -0.5 * i + 0.1),      # 2点目
        dimstyle=dimstyle,            # 適用する寸法線スタイル
    )
    dim.render()

EZ_M_〇〇_H25_CM系の名前は、図面の縮尺(〇〇分の1)ごとに寸法の文字高が調整されたプリセットです。AutoCADで使う縮尺に合わせて選ぶと、都度サイズを計算する手間が省けます。

参考:公式ドキュメント(DimStyle Table Entry)

setupの中身を確認「visualstyles

visualstylesは25種類プリセットされる3D表示用のスタイルです。3D対応CADでもAutocad環境でないと正確に表示されないようで、当方で表示確認することが出来ませんでした。

つかだ

当方は3D対応CADを所持していないため、実際の見た目までは確認できていません。ご紹介まで……
Auto CADをお使いの方はぜひ試してみてください。

【検証】3つのCADビューアで試してみました

visualstylesは他の3つ(linetypes・styles・dimstyles)と違い、個々の図形に貼る属性ではなく、ペーパースペース上の「ビューポート」という表示領域に適用する設定です。3D形状のメッシュを作り、25個のビューポートにそれぞれ異なるvisualstyleを割り当てたテスト用DXFを作成し、無料で使える3つのCADやビューアで確認してみました。

ビューア結果
FreeCADビューポート・visualstylesとも非対応。モデルスペースの形状のみ表示
NijiCADラベルの文字は表示されるが、ビューポート内の陰影は非対応
Autodesk Viewer(Web版)ペーパースペースのシートは認識するが、ビューポート内の陰影は非対応

3つとも同じ理由で陰影が表示されませんでした。visualstylesの陰影表示は、AutoCADのペーパースペース機能に深く依存した仕組みのようで、軽量なビューアでは実装されていないようです。デスクトップ版のAutoCADやBricsCADをお持ちの方は、ぜひ試した結果を教えてください。

参考:公式ドキュメント(Drawing Management/setup引数の一覧)

まとめ

今回は、ezdxfのインストールから最短5行での作図、そしてsetup機能によるフォント・線種・寸法線の一括プリセットまでを解説しました。

  • 作図の基本は「新規作成 → モデルスペース取得 → 図形を追加 → 保存」の4手順
  • matplotlibアドオンでCADを開かずにプレビューできる
  • setup=Trueで線種・フォント・寸法線・表示スタイルを一括プリセット
  • プリセットのフォントは英字のみ。日本語表示には別途フォント追加が必要

次回は、線・円・弧・ポリラインといった図形の描画方法と、レイヤー・色・線幅・日本語フォントなどの属性をまとめて解説します。寸法線は第3回で扱います。

JupyterLab上で3Dビューアを見ながら作図したい場合は、以前紹介した「JupyterCAD」も参考にしてください。

よかったらシェアしてね!
  • URLをコピーしました!

コメントお待ちしてます!

コメントする

CAPTCHA


目次