【Fusion360×python】3Dモデルのスクショ(自動トリミング)

プログラミング

はじめに

Fusion360×python(プログラミング)

面倒な作業を機械に任せることを目標にプログラミングも勉強していきます。

筆者
筆者

Fusion360の使用経験3ヶ月(2022.5月サブスク契約)

プログラミング初心者

Hello Worldから挑戦😀

実現したい機能

  • 3Dモデルのスクリーンショット
  • 現在時刻で名前を保存

実行するたびに、新しい名前で保存されていく仕組みづくりです。

筆者
筆者

Fusion360でつくった3DモデルをSNSに公開するための画像作成です

Instagramに投稿するために画像を正方形に加工したい

今までしていた方法

  1. スクリーンショットの撮影(windowsの標準機能)
  2. トリミング

マウス操作が中心なので、頑張って作業しても1分はどうしてもかかってしまう…

3Dモデルをたくさんつくるとアップロードする機会も増えてくるので、このムダ時間をもったいなく感じます。そこでプログラムにより、省力化していきたいと思います。

3Dモデルのスクリーンショット

プログラムの流れ

  1. ビューポートの更新
  2. スクリーンショット保存

ビューポートの更新

関数化することで、メイン文から呼び出す方式

#3Dモデルのサイズに画面を再設定
def view_move(app):
    view1 = app.activeViewport
    camera1 = view1.camera
    camera1.isFitView =  True
    view1.camera = camera1

スクリーンショットの撮影

画像サイズ(750×750)設定しています。使いたいサイズで保存可能です。

※750×750のサイズには、意味がありませんので、お好きなサイズを入力でOKです。

#スクリーンショットの保存
app.activeViewport.saveAsImageFile('任意のファイル名.jpg', 750, 750)

ここで気になるのが、毎回「任意のファイル名.jpg」で保存されてしまうということ。
保存した「任意のファイル名.jpg」を毎回移動させないと、上書き保存されてしまうため、Fusion360上で操作を続けることができません。
Fusion360(ソフト)とフォルダー(保存先)を行ったり来たりすることになってしまいます。

デュアルディスプレイにしていればこの問題が少し解消される?

  • メインディスプレイ:Fusion360
  • サブディスプレイ:保存先での操作(名前を変えて保存、別フォルダへの移動)

マウス操作が入ってしまうので、根本的な解決にはならないです。

ファイル名に「現在時刻」の情報を組み込むことにより、この問題を解決狙います。

現在時刻の獲得

プログラムを実行したタイミングの現在時刻の抽出。「datetime」をインポートします。

import datetime

現在時刻を獲得するための処理を追加

#現在時刻の獲得
dt = datetime.datetime.now()
情報
dt.year年(2022)
dt.month月(7)
dt.day日(29)
dt.hour時(15)
dt.minute分(25)
dt.second秒(31)

以上を連結することで「2022729152531」という文字列を得ることができます。
これをファイル名にします。
→ 2022年7月29日15時25分31秒 という意味の文字列

時々刻々と変わるため、プログラムを実行するたびに保存名が変わります。
1秒以内に終わる操作の場合、この方法を適応しにくいと考えています。
※for文などでプログラム内で軽い処理を繰り返すことが懸念点
ミリ秒も取得できるので、当該処理をするときには、1手間かかりますが、問題解決できます。

dt = datetime.datetime.now()
date_code1 = dt.year
date_code2 = dt.month
date_code3 = dt.day
date_code4 = dt.hour
date_code5 = dt.minute
date_code6 = dt.second

data_code1~6に「年月日、時間」を格納していきます。
最後は、ファイル名の連結。賢さが消えた、力づくな1行。

date_code = str(date_code1) + str(date_code2) + str(date_code3) + str(date_code4) + str(date_code5) + str(date_code6)

最終的なプログラム

以上の内容より、下記プログラムが最終的な姿となります。

import adsk.core, adsk.fusion, adsk.cam, traceback
import datetime

image_name = 任意のフォルダ

#3Dモデルのサイズに画面を再設定
def view_move(app):
    view1 = app.activeViewport
    camera1 = view1.camera
    camera1.isFitView =  True
    view1.camera = camera1

#メイン文
def run(context):
    
    ui = None

    try:

        app = adsk.core.Application.get()
        ui = app.userInterface

        #スクショ撮影
        view_move(app)

        #現在時刻の取得
        dt = datetime.datetime.now()
        date_code1 = dt.year
        date_code2 = dt.month
        date_code3 = dt.day

        date_code4 = dt.hour
        date_code5 = dt.minute
        date_code6 = dt.second

        date_code7 = str(date_code1) + str(date_code2) + str(date_code3) + str(date_code4) + str(date_code5) + str(date_code6)

        #スクショ保存S
        app.activeViewport.saveAsImageFile(image_name+date_code7+'.jpg', 750, 750)

        #終了報告
        app.userInterface.messageBox('スクリーンショット保存しました') 

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

もう少し賢いプログラムへの改良

ファイル名の設定部分が、ちょっとスマートではない感じ。
個人的な好みの問題です。

作戦1:リストの活用
していることは同じ処理。あまり変わらない外観。
文字の合成を2行に分割してごまかす。

date_code = [0,0,0,0,0,0]

date_code[0] = dt.year
date_code[1] = dt.month
date_code[2] = dt.day

date_code[3] = dt.hour
date_code[4] = dt.minute
date_code[5] = dt.second

date_code2 = str(date_code[0]) + str(date_code[1]) + str(date_code[2])
date_code3 = str(date_code[3]) + str(date_code[4]) + str(date_code[5])

作戦2:for文の適用

ファイル名の合成部分をfor文にすることで少しすっきり

ファイル名がすべて20XX年から始まる。
21XX年まで使うことがないから、先頭の2文字はなくてもいいのでは?
「220729」で2022年の7月29日というのがわかる。

今年は「2022年」なので、2022という値を得ることが可能です。
そのため、「2000」を引いて残った「22」が必要な情報となります。

date_code = [0,0,0,0,0,0]

date_code[0] = (dt.year-2000) * pow(10,10)
date_code[1] = dt.month       * pow(10,8)
date_code[2] = dt.day         * pow(10,6)

date_code[3] = dt.hour        * pow(10,4)
date_code[4] = dt.minute      * pow(10,2)
date_code[5] = dt.second

f_name = 0

for counter in range(6):
	f_name+=date_code[counter]

#スクショ保存
app.activeViewport.saveAsImageFile(image_name+str(f_name)+'.jpg',750,750)

おわりに

Fusion360×python(プログラミング)

面倒な作業を機械に任せることを目標にプログラミングも勉強していきます。

いままでスクリーンショットを撮影して、手作業でトリミングしていた作業を、プログラム実行ポチリで終了。指定しているフォルダにどんどん保存されていきます。