2026年2月1日日曜日

FreeCADのpythonでspreadsheetの値を変更しつつオブジェクトをエクスポート


背景

FreeCADでspreadsheetを利用して作ったオブジェクトの値を変えつついくつかの種類を生成したい場面があったので、pythonコンソールを利用してshpreadsheetの値を書き換える方法とオブジェクトのエクスポート方法を把握しました。
備忘録として方法を記事に残します。

要点

記事で紹介するプログラムを作成する際に重要だった点を先に共有します

要点1: spreadsheetはシート名で呼び出してgetやsetでaliasの値を扱える

下記のように呼び出して値の代入ができました。
setの第2引数は文字列である必要がありました。
doc = App.ActiveDocument
sheet = doc.Spreadsheet
sheet.set("outer_x", str(10))

参考
how to update Spreadsheet values using FreeCAD python module

要点2: spreadsheetで更新した値をオブジェクトに反映させるにはドキュメント全体の更新が必要そう

spreadsheetに対してset関数で値を代入後にその値が適用されたモオブジェクトを生成する場合は、自分が試した範囲ではプロジェクトに対してrecomputeを実行する必要がありました。
オブジェクトやspreadsheetのrecompouteやGUIの更新や数秒待機(time.sleep)などは無意味でした。
# obj.recompute()
# FreeCADGui.updateGui()
# time.sleep(1)
doc.recompute()

変更したspreadsheetの値をオブジェクトに反映させる他の高速な更新方法をご存知でしたら、コメントなどで教えていただけると嬉しいです。

要点3: オブジェクトのstlファイルへのエクスポートはMeshを介して行う

stlファイルとしてエクスポートしたい場合、Meshをインポートして行います。
オブジェクトは配列で渡す必要があります。
import Mesh
Mesh.export([obj], "some.stl")

マウス操作時後にpythonコンソールに表示された内容から把握しました。

使ったもの

FreeCAD 1.0.2
spreadsheetを利用したドキュメント(FreeCADのファイル)

ドキュメントではエイリアスを割り当てたspreadsheetの値を参照して枠を作っています。




コード解説

全体を共有後に要所を解説します。
ドキュメントのspreadsheetの「outer_x」と「outer_y」を変えつつ、変えた値が反映されたオブジェクトをstlファイルとしてエクスポートするコードです。

import Mesh
import time

label_object = "Mirrored001"
dirname_export = "exported_stl"
name_prefix = "round_frame"

list_size_and_label = [
[30, 30, "square_small"],
[90, 90, "square_big"],
[40, 80, "rectangle_middle"],
]

doc = App.ActiveDocument
sheet = doc.Spreadsheet
obj = doc.getObjectsByLabel(label_object)[0]

dir_export = os.path.join(os.path.dirname(doc.FileName), dirname_export)
os.makedirs(dir_export, exist_ok=True)

def update_size(outer_x, outer_y):
sheet.set("outer_x", str(outer_x))
sheet.set("outer_y", str(outer_y))
sheet.recompute()

def export_obj_as_stl_by_label(obj, label):
Mesh.export([obj], os.path.join(dir_export, label + ".stl"))

for (outer_x, outer_y, label) in list_size_and_label:
update_size(outer_x, outer_y)
doc.recompute()
label = "%s_%.1f_%.1f_%s" % (name_prefix, outer_x, outer_y, label)
export_obj_as_stl_by_label(obj, label)

配列第1要素をx方向の長さ、第2要素をy方向の長さ、第3要素を名前として定義し、forで回しています。
list_size_and_label = [
[30, 30, "square_small"],
[90, 90, "square_big"],
[40, 80, "rectangle_middle"],
]

for (outer_x, outer_y, label) in list_size_and_label:
update_size(outer_x, outer_y)


要点1として述べた通り、spreadsheetはシート名で呼び出し、set関数に文字列を与えることで値を更新できます。
sheet = doc.Spreadsheet

def update_size(outer_x, outer_y):
sheet.set("outer_x", str(outer_x))
sheet.set("outer_y", str(outer_y))
sheet.recompute()

要点2として述べた通り、spreadsheetの値更新後はドキュメントのrecompouteを呼び出してオブジェクトへの値の反映が必要です。
    update_size(outer_x, outer_y)
doc.recompute()
label = "%s_%.1f_%.1f_%s" % (name_prefix, outer_x, outer_y, label)
export_obj_as_stl_by_label(obj, label)

要点3として述べたとおり、stlファイルへのエクスポートはMeshのexport関数で行います。
その際のモデルの受け渡しは配列である必要がありました。
stl以外の方法でエクスポートしたい場合はpythonコンソールを開いた状態でエクスポート操作を行い表示される内容を確認してください。
import Mesh

def export_obj_as_stl_by_label(obj, label):
Mesh.export([obj], os.path.join(dir_export, label + ".stl"))

動作結果

上記のプログラムを実行した結果、期待通りに3種類のstlファイルを生成できました。



おわり

FreeCADのspreadsheetの値をpythonで書き換える方法と、その値が反映されたオブジェクトをエクスポートする方法を把握できました。
似たような形状で多種のオブジェクトの生成が必要な場合に便利です。

参考

how to update Spreadsheet values using FreeCAD python module

0 件のコメント :