この記事はTakumi Akashiro ひとり Advent Calendar 2020の11日目の記事です。
昨日 (PythonからCOMオブジェクトを扱う - Qiita) に引き続き、
今日はSubstance DesignerからPhotoshopへ出力したテクスチャを送ります。
昨日と同じネタを擦るな!と灰皿が飛んでくるかもですが、
便利そうで、出来そうなことはなるべくやるのが私のモットー(?)なのでやります。
それに、今後の仕事で必要な瞬間が来る予感がしますし。
とりあえず作る
テクスチャをtempフォルダに書き出して、
Photoshopで開き、開いているドキュメントのレイヤーにコピーして、閉じるだけです。
特にそれ以外は技術的に解説することはないので、とりあえず作ります。
import gc
import pathlib
import tempfile
import sd
from PySide2 import QtWidgets
# 拡張モジュール。詳細は昨日の記事参照。
import comtypes.client
def get_photoshop_client():
client = comtypes.client.GetActiveObject("Photoshop.Application")
if client:
return client
else:
return comtypes.client.CreateObject("Photoshop.Application")
def is_exist_document(client):
return bool(len(list(client.documents)))
# def get_output_size():
# 出力するテクスチャ解像度を取得する
# NOTE:
# 当初はテクスチャ解像度を取得して、ドキュメントがなければ生成、
# 既に開かれていれば、Photoshopの開いているドキュメントのサイズと比較、
# 違ったらconfirmDialogを出すとかやりたかった。倍解像度で送ってリサイズ…とかする人もいるので不要かもだが。
# だが、テクスチャ解像度をピクセル単位で取得するすべが分からない……ので断念。
# Relativeの元の値はどこに格納されてンだよ…
# pass
def export_texture_to_temp_folder(sd_graph):
export_path = tempfile.gettempdir()
sd.tools.export.exportSDGraphOutputs(sd_graph, export_path, 'png')
path = str(pathlib.Path(export_path) / (sd_graph.getIdentifier() + "_output_0.png"))
return path
def send_texture_to_photoshop(ps_client, path):
document = ps_client.activeDocument
ps_client.open(path)
ps_client.activeDocument.artLayers[0].duplicate(document)
ps_client.activeDocument.close()
def main():
ps_client = get_photoshop_client()
sd_app = sd.getContext().getSDApplication()
sd_uimgr = sd_app.getQtForPythonUIMgr()
sd_graph = sd_uimgr.getCurrentGraph()
# sd_size = get_output_size()
if is_exist_document(ps_client) is False:
print(is_exist_document(ps_client))
sd_mainwindow = sd_uimgr.getMainWindow()
message = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, "TextureSender", "Photoshopでドキュメントを開いてから実行してください", parent=sd_mainwindow)
message.show()
return
texture_path = export_texture_to_temp_folder(sd_graph)
send_texture_to_photoshop(ps_client, texture_path)
del ps_client
gc.collect()
main()
結構いい感じですね!
締め
SubstanceDesingerのPythonモジュールは叩いて2日ぐらい1でしたが、どうにかそれっぽくはなりましたね!
……Outputノードが複数あるときの挙動とか、OutputNodeの名前を直書きしてるとか、
前に送った奴はレイヤー名とかロック状態とか参照して消したいとか、いろいろ思うところはありますが、
時間が全く足りないので今回はここまでで!
では!
参考
【SubstanceDesigner】Pythonでテクスチャを出力|三味松ブログ
-
正味6時間ぐらい?先人のおかげで10分ぐらいでテクスチャは出力出来て、内4時間ぐらいはテクスチャサイズの取得に使ってた。
SDPropertyが理解できたのは収穫だった。 ↩