ページ

2025年12月9日火曜日

FreeCADでpythonを使いPartの面をTechDrawに置いてDXFファイルを書き出す


背景

FreeCADとはオープンソースの3D CADプログラムです。
FreeCADの内部処理はpython APIに対応しており、マウス操作でできることはpythonでも行えることが多いです。
モデル(Part)を作り、それの面をTechDrawで描いてDXFファイルとして書き出す処理を自動化したかったので、その方法を把握しました。
備忘録として関連情報と共に記事に残します。

使ったもの

FreeCAD 1.0.2

pythonコンソールを表示

表示 -> パネル -> Pythonコンソール を選ぶとpython実行画面が表示されます。


マウス操作を行うと該当するpythonの処理が表示されるので、pythonで制御したい処理をマウス操作すると、必要なコマンドの雰囲気をつかめます。


参考
Python scripting tutorial
Pythonスクリプトのチュートリアル

プログラム

export_xy_as_dxfという名前のgroupの中にあるモデルをDXFファイルに書き出すプログラムです。
全体を説明後に解説します。
import FreeCAD
import TechDraw
import time

doc = FreeCAD.activeDocument()
objects_of_group = doc.getObjectsByLabel("export_xy_as_dxf")

if objects_of_group == []:
print(objects_of_group)
exit(0)
# return 0

dir_doc = os.path.dirname(doc.FileName)

template = doc.addObject('TechDraw::DrawSVGTemplate', 'Template')
template.Template = os.path.join(FreeCAD.getHomePath(), "share/Mod/TechDraw/Templates/Default_Template_A4_Landscape.svg")
page = doc.addObject('TechDraw::DrawPage', 'page_plate')
page.Template = template

def put_part_xy_side_as_view(page, part):
view = doc.addObject('TechDraw::DrawProjGroupItem', 'View')
view.translateLabel('DrawProjGroupItem', 'View', 'View')
view.Source = part
page.addView(view)
view.Direction = FreeCAD.Vector(0, 0, 1)
view.RotationVector = FreeCAD.Vector(1, 0, 0)
view.XDirection = FreeCAD.Vector(1, 0, 0)
view.recompute()
return view

def export_view_to_dxf(view):
path_file = os.path.join(dir_doc, view.Source[0].Name + ".dxf")
TechDraw.writeDXFView(view, path_file)

for part in objects_of_group[0].Group:
view = put_part_xy_side_as_view(page, part)
time.sleep(1)
export_view_to_dxf(view)

FreeCADで閲覧中のドキュメントのexport_xy_as_dxfを探し、無かったら処理を止めます。
doc = FreeCAD.activeDocument()
objects_of_group = doc.getObjectsByLabel("export_xy_as_dxf")

if objects_of_group == []:
print(objects_of_group)
exit(0)
# return 0

グループの作り方は下記のフォーラムで紹介されています。
日本語フォーラム グループ化のような機能はありますか?


ドキュメントはFileNameで絶対パスを取得できるので、保存先としてドキュメントがあるディレクトリを変数に保持しておきます。
dir_doc = os.path.dirname(doc.FileName)

TechDrawのpageを作ります。
GUIの場合はTeachDraw_PageDefaultが実行されますが、自分が試した範囲ではdoCommandでそれを実行してもエラーになってpageを作れなかったので、手動で作成してテンプレートを手動で割り当てました。
TechDraw_API の説明書も参考になります。
template = doc.addObject('TechDraw::DrawSVGTemplate', 'Template')
template.Template = os.path.join(FreeCAD.getHomePath(), "share/Mod/TechDraw/Templates/Default_Template_A4_Landscape.svg")
page = doc.addObject('TechDraw::DrawPage', 'page_plate')
page.Template = template

Partのxy面をviewとしてpageに描画する関数です。
view.Directionに渡すVectorを変えれば、投影面を変えれます。
viewのSourceにPartを割り当てることで、描画対象のPartを紐付けれます。
def put_part_xy_side_as_view(page, part):
view = doc.addObject('TechDraw::DrawProjGroupItem', 'View')
view.translateLabel('DrawProjGroupItem', 'View', 'View')
view.Source = part
page.addView(view)
view.Direction = FreeCAD.Vector(0, 0, 1)
view.RotationVector = FreeCAD.Vector(1, 0, 0)
view.XDirection = FreeCAD.Vector(1, 0, 0)
view.recompute()
return view

viewをDXFファイルに書き出す関数です。
Sourceの0番目の要素であるPartの名前でDXFファイルを生成します。
右クリックでエクスポート時のPythonコンソールを観察するとTechDraw.writeDXFPageが使われていますが、view用の関数で十分だったのでTechDraw.writeDXFViewを使いました。
def export_view_to_dxf(view):
path_file = os.path.join(dir_doc, view.Source[0].Name + ".dxf")
TechDraw.writeDXFView(view, path_file)

groupの中にあるPartをviewとして描画してDXFファイルに書き出します。
viewに書き出した直後にDXFファイルへの書き出しを実施すると空になってしまうので、sleepで1秒待ってから書き出しを行っています。
for part in objects_of_group[0].Group:
view = put_part_xy_side_as_view(page, part)
time.sleep(1)
export_view_to_dxf(view)

上記のtime.sleep(1)をせず描画終了を認識する方法をご存知でしたら、コメントなどで教えていただけると嬉しいです。

dxfを生成できました。


おわり

FreeCADでpythonを利用してPartのxy面をDXFファイルに書き出せました。
マウス操作でpythonコンソールに出てくる情報だけでは、pageへのテンプレート割当、view.Sourceの使い方、writeDXFView関数の存在が分からず試行錯誤が必要でしたが、その結果期待する動作をさせれて良かったです。

参考

FreeCAD公式の説明書です。
日本語版もありはしますがページを進めると日本語版が存在しなくなるので、そうなったら英語版に頼るのが良いです。
Python scripting tutorial
Pythonスクリプトのチュートリアル

グループの作り方を把握したフォーラムです。
日本語フォーラム グループ化のような機能はありますか?

TechDrawの説明書のgithubのページです。
TechDraw_API

0 件のコメント :

コメントを投稿