Mayaでテクスチャをリサイズしたいな と思いまして。
正確に言うと、
レンダリング用のテクスチャは4Kとかとても大きいサイズの場合があり、
アニメーション作業時にそれらのテクスチャーを読ませるとビューポートがおかしくなることがあるので、
アニメーション作業用にテクスチャのサイズを小さくしたものを用意したいなと
※viewPort2.0の機能でプレビュー時にテクスチャをリサイズしてくれる機能もありますが、比較した結果元のファイルから解像度が低い方がGPUへの負荷が低かったです。
さて、
やり方は幾つか思いつくのですが、Mayaの基本機能のTestTextureでなんかできそうなきがするので掘り下げてみます。
調査
とりあえず testTextureを実行し、scriptEditorを見てみると
compositeTest 256 256;
だそうですので、更に追ってみると
whatIs compositeTest;
// Result: Mel procedure found in: C:/Program Files/Autodesk/Maya2022/scripts/others/compositeTest.mel //
該当のファイルを覗いてみると
global proc compositeTest(int $width, int $height){
int $start = `currentTime -query`;
int $end = $start;
string $imageName = "testComp";
string $fileFormat = "iff";
composite $width $height $imageName $fileFormat images $start $end 1 4 0;
}
もうひと声
whatIs composite;
// Result: Mel procedure found in: C:/Program Files/Autodesk/Maya2022/scripts/others/composite.mel //
で、行きついた先でみつけたのが
convertSolidTx -samplePlane true
-alpha true
-resolutionX $xRes
-resolutionY $yRes
-name "testComp"
-fileFormat $fileFormat
-fileImageName $fileImageName
;
という箇所です。
どうやらこういうコマンドのようです。
オプションはいっぱいありますが、composite.mel内で使われている内容をみると割と素直なようにも見えますね。
ん~なんか色々できそうなオプションがそろってますね。
コマンドをテスト
とりあえず、簡単なシーンでテストしてみます。
ノードを指定して実行すると、
- fileImageName で指定したパスに画像を保存
- name で指定したfileノードを作成
- 保存した画像を読ませる
までをやってくれるんですね。
name で指定したノード名が存在する場合は、どうなるんでしょうか?
試しにターゲットのnodeと作られるfileNodeの名前を同じにして実行してみます。
(もしかしたら既存のノードのパスを書き換えてくれるかもしれないという望みを・・・)
cmds.convertSolidTx(
"file1",
samplePlane =True,
name = "file1",
fileImageName= "C:/Users/y9bos/Desktop/resize_BGimage.jpg",
fileFormat = "jpg",
force = True,
resolutionX = 256,
resolutionY = 256
)
結果としては
なるほど、どうあっても新規ノードを作成するようですね。
実装
ファイルノードに対して実行するとこんな感じですかね。
import os
import maya.cmds as cmds
def reSizeTexture(targetNode,resizeTo,fileFormat,overwrite = False,exportDirPath = None):
curFilePath = cmds.getAttr(targetNode + ".fileTextureName")
curDirPath = os.path.dirname(curFilePath) + "/"
curFileNname = os.path.basename(curFilePath)
curImageFormat = curFileNname.split(".")[-1]
curRes = cmds.getAttr(targetNode + ".outSize")[0]
convertdFileName = "resized_" + curFileNname.replace("." + curImageFormat, "." + fileFormat)
if exportDirPath == None:
exportDirPath = curDirPath
scaleRatio = 1.0
##define size
if curRes[0] > resizeTo or curRes[1] > resizeTo:
scaleRatio = min([resizeTo / curRes[0], resizeTo / curRes[1]])
if scaleRatio == 1.0:
return
resolutionX = curRes[0] * scaleRatio
resolutionY = curRes[1] * scaleRatio
if os.path.exists(exportDirPath) ==False:
os.makedirs(exportDirPath)
convertdFilePath = exportDirPath + convertdFileName
cmds.convertSolidTx(
targetNode,
samplePlane =True,
name = "resizeTmp",
fileImageName= convertdFilePath,
fileFormat = fileFormat,
force = overwrite,
resolutionX = resolutionX,
resolutionY = resolutionY
)
cmds.delete("resizeTmp")
cmds.setAttr(targetNode + ".fileTextureName",convertdFilePath, type = "string")
テスト
reSizeTexture("file1",256,"jpg",overwrite = False,exportDirPath = None)
実行結果は、
課題
対応できてない状況
- UDIM とか連番ファイルの場合
- 同一ファイルを別ノードで読んでて、個別にアトリビュートで色をいじってる場合
- ファイルノードでの読み込み時のカラーマネージメントで逆ガンマがかかってる場合
すべてに対応するとなるとまだまだ検証は必要そうです。