Python 「FreeCAD」寸法をパラメータにCADファイル(.step)をCUIで自動生成する【Windows用】

#'21/02/13更新

 本記事ではpandasを使用しない雛形コードを載せました。この理由は、FreeCAD内のPythonのみを使用することでpythonのver違いの干渉によるエラーを回避するためです(FreeCADのインストール方法は次のリンク先に記載していますhttps://hk29.hatenablog.jp/entry/2020/07/04/122953)。Linuxの場合の雛形コードは次のリンク先ですhttps://hk29.hatenablog.jp/entry/2021/02/13/235536)。

 以降では、本題のPythonスクリプトについて説明します。
FreeCADで作成したCADデータ(.FCStdファイル)を元に、Pythonスクリプトで自動で寸法を変更し、CADファイルの汎用フォーマット.stepで保存してゆく仕様です。下図はFreeCADで作成した3次元構造の例です。

f:id:HK29:20200704111752j:plain

下図のように、Sketcherワークベンチで定義した寸法を自動で変更したいとします。

f:id:HK29:20200704111612j:plain

こういった場合、下図のようにSpreadsheetワークベンチで定義した値をリンクしておきます。これにより、変数をひとつの表で一元管理できます。この方法は次のリンク先が参考になります。FreeCAD 寸法をスプレッドシートで管理する - XSim

f:id:HK29:20210126002601p:plain

次に、寸法をパラメータとした水準表をcsvファイルで下図のように作成します。一番左の列は水準Noです。csvファイルに記載する列名は、FreeCADのSpreadsheetのプロパティにあるエイリアスで定義した名称と同じです。大文字小文字は区別されることに注意。

f:id:HK29:20200704113347j:plain

大量の水準を作成したい場合は次のリンクを参考下さい。VBA エクセルで水準表を作成する - PythonとVBAで世の中を便利にする

PythonのFreeCADライブラリをインポートするため、本コード内でFREECADPATHにFreeCADのbinフォルダの絶対パスを通します。下図がその例で、Pythonスクリプトの冒頭で定義します。

f:id:HK29:20210126003133p:plain

スクリプトPython実行には、FreeCAD内にあるPython絶対パスで指定する
下図は、実行例です。00_freecad2.pyが本雛形コードのファイル名でその左側にある長いのがFreeCADにあるPythonのパスです。ここで、そのパスの両端をダブルクォーテーション""で挟むことでパス内にスペース等があっても確実に指定できます。(図中のprint出力は、csvファイルをpandasでなくて読み込んだ結果です)f:id:HK29:20210126002053p:plain

その後、最終的に下図のようにCADファイルのひとつである汎用フォーマットの.stepで複数出力します。

f:id:HK29:20210126003645p:plain

下図は、上記8つのCADファイルです。異なる寸法の構造が作成されたことがわかります。

f:id:HK29:20200704115906j:plain
■本プログラム

# PythonのFreeCADライブラリをインポートするため、下記FREECADPATHにはFreeCADの絶対パスを通します。
FREECADPATH = r'D:\00_backup\01_new\FreeCAD_0.19.21280-Win-Conda_vc14.x-x86_64\bin'
import os, sys
sys.path.append(FREECADPATH)
import FreeCAD
import Import

class Make_CADfiles:
    # 初期化(インスタンス化)
    def __init__(self, input_path, output_dirpath):
        self.input_path = input_path
        num = os.path.basename(input_path).rfind('.')
        self.file_name = os.path.basename(input_path)[:num]
        #print(self.file_name)
        self.output_path = output_dirpath

    # FreeCADファイルを読み込む(.FCStd)
    def load_fcstd_file(self):
        FreeCAD.open(self.input_path)

    # パラメータ変更
    def replace_param(self, param, value):
        FreeCAD.setActiveDocument(self.file_name)
        FreeCAD.ActiveDocument.Spreadsheet.set(param, value)
        FreeCAD.ActiveDocument.recompute()
        __objs__=[]
        __objs__.append(FreeCAD.getDocument(self.file_name).getObject(my_object))
        del __objs__

    # CADファイル出力(.step)
    def export_cadfile(self, num):
        save_file_path = os.path.join(self.output_path, self.file_name + '_' + str(num) + '.step')
        __objs__=[]
        __objs__.append(FreeCAD.getDocument(self.file_name).getObject(my_object))
        Import.export(__objs__, save_file_path)
        del __objs__


def main():
    # csvファイルを読み出し(pandasを使わない)
    with open(parameter_list_path, 'r') as f:
        list_of_data_list = []
        for i, row in enumerate(f, 1):
            row = row.rstrip('\n')
            if i==1:
                column_name_list = row.split(',')[1:]
                print(column_name_list)
            else:
                data = row.split(',')[1:]
                list_of_data_list.append(data)
    print(len(list_of_data_list))
    print(list_of_data_list)
    
    # csvの行データを順に取り出し
    for i, data_list in enumerate(list_of_data_list, start=1):
        # オブジェクト生成
        f = Make_CADfiles(input_path, output_dirpath)
        # ファイルを読み出し
        f.load_fcstd_file()

        # csvの列方向へループして、パラメータを抽出する
        check_params = []
        for column_name, data in zip(column_name_list, data_list):
            #print(column_name, data)
            # データを置換
            f.replace_param(column_name, str(data) + 'mm')
            check_params.append((column_name, str(data)))

        # ループが終わったとこでCADファイルへ書き出す
        f.export_cadfile(i)
        print(i, check_params)
        
        # オブジェクト削除
        del f


if __name__ == '__main__':
    input_path ='./test7.FCStd' # 雛形のFreeCADファイルパス
    output_dirpath ='./CAD_stepfiles' # 保存するフォルダパス
    parameter_list_path = 'parameter_list.csv' # パラメータ記載のcsvファイル
    my_object = 'BooleanFragments' # FreeCADで作成した対象のオブジェクト
          
    main()
    print('finished')

最後に、Python向けのFreeCADモジュールの説明は、FreeCADのGUIのメニューバーにある「ヘルプ>Pythonモジュールのマニュアル」で調べることが出来ます。

以上

<広告>