今回の案件でテクスチャはTGA 24bit RLE圧縮という指定がありまして、それをチェックが出来るツールを書こうとしていました。
まずは既に書いてある物をネットで探して、使えそうなモジュールはこれでした:
pyTGAhttps://github.com/MircoT/pyTGATGAを読み込んだり、書き出したり出来るモジュールです。
そして、全てデフォルトのPythonで動くモジュールです!
全てPythonだから好きに編集が出来るけど、処理が重いのかなという心配もあります。
とりあえず試してみます。
使い方を読んで、以下のコマンドで欲しかった情報を取得ができました。
image = pyTGA.Image()
image.load( texture_filePath )
print image._header.pixel_depht
しかし、重い。
1枚数十秒だったので、4K テクスチャを数十枚を確認するには向いていませんね・・・。
どうやら load でテクスチャのデータを全て読み込んでいるようで、かなり時間が掛かってしまいます。
でも、欲しいのはヘッダーの部分だけ。
テクスチャのデータとかはいらないので、色々弄ってみて以下のコードに変わりました。
あっちこちの調整も必要があったけど、主にヘッダーの読み込みに役に立ちそうな部分だけを残して、あとは削除する作業でなんとかなりました:
from struct import unpack
def dec_byte(data, size=1, littleEndian=True):
"""Decode some data from bytes.
Args:
data (bytes): data to decode
size (int): number of bites of the data
littleEndian (bool): little endian or big endian
Returns:
int: the decoded data
"""
order = str('<' if littleEndian else '>')
format_ = str((None, 'B', 'H', None, 'I')[size])
return unpack(order + format_, data)[0]
class TGAHeader(object):
"""
#- Field(1)
# ID LENGTH (1 byte):
# Number of bites of field 6, max 255.
# Is 0 if no image id is present.
#
#- Field(2)
# COLOR MAP TYPE (1 byte):
# - 0 : no color map included with the image
# - 1 : color map included with the image
#
#- Field(3)
# IMAGE TYPE (1 byte):
# - 0 : no data included
# - 1 : uncompressed color map image
# - 2 : uncompressed true color image
# - 3 : uncompressed black and white image
# - 9 : run-length encoded color map image
# - 10 : run-length encoded true color image
# - 11 : run-length encoded black and white image
#
#- Field(4)
# COLOR MAP SPECIFICATION (5 bytes):
# - first_entry_index (2 bytes) : index of first color map entry
# - color_map_length (2 bytes)
# - color_map_entry_size (1 byte)
#
#- Field(5)
# IMAGE SPECIFICATION (10 bytes):
# - x_origin (2 bytes)
# - y_origin (2 bytes)
# - image_width (2 bytes)
# - image_height (2 bytes)
# - pixel_depth (1 byte):
# - 8 bit : grayscale
# - 16 bit : RGB (5-5-5-1) bit per color
# Last one is alpha (visible or not)
# - 24 bit : RGB (8-8-8) bit per color
# - 32 bit : RGBA (8-8-8-8) bit per color
# - image_descriptor (1 byte):
# - bit 3-0 : number of attribute bit per pixel
# - bit 5-4 : order in which pixel data is transferred
# from the file to the screen
"""
def __init__(self, file_name):
with open(file_name, "rb") as image_file:
# Read Header
image_file.seek(0)
# ID LENGTH
self.id_length = dec_byte(image_file.read(1))
# COLOR MAP TYPE
self.color_map_type = dec_byte(image_file.read(1))
# IMAGE TYPE
self.image_type = dec_byte(image_file.read(1))
# COLOR MAP SPECIFICATION
self.first_entry_index = dec_byte(image_file.read(2), 2)
self.color_map_length = dec_byte(image_file.read(2), 2)
self.color_map_entry_size = dec_byte(image_file.read(1))
# IMAGE SPECIFICATION
self.x_origin = dec_byte(image_file.read(2), 2)
self.y_origin = dec_byte(image_file.read(2), 2)
self.image_width = dec_byte(image_file.read(2), 2)
self.image_height = dec_byte(image_file.read(2), 2)
self.pixel_depth = dec_byte(image_file.read(1))
self.image_descriptor = dec_byte(image_file.read(1))
これで欲しかった情報を一瞬で読み込むことが出来ました。
テクスチャの作り方にミスがあったかどうかはすぐに分かる。
tga = TGAHeader( texture_filePath )
print tga.image_type #3以下の場合は圧縮なし
print tga.image_height #高さ
print tga.image_width #横幅
print tga.pixel_depth #24bit か 32bit
そして何もインストールする必要がない!
チェックツール1つだけで済むというのも嬉しいですね。
元々Mayaユーザーのデザイナーは今の案件の都合によってSoftimageを使っています。 Softimageユーザとして少しアドバイスしたりしていて、キャラクターのポーズを付ける時にオートキーフレームにした方が楽かもよーと教えたら、Softimageの画面のフチが赤くなったことに驚きました。 これは分かりやすいですね!
Mayaだとオートキーが付いているのを忘れて、色々失敗してしまいますね。
そっか、Mayaにはないですね。こういう目印。
Softimage 2011 か 2012 までもそうだったから、良く分かります。オートキーに気付かずにキーを打ちまくるからなるべくオートキーは使わないようにしていました。
で、Mayaでもなんとか出来ないかなと考え、このやり方を思い出した。
Maya | UIの色変更これをイベントにすればなんとかなるじゃん!
と思ったけど、実行してみると、エラーが出ました。
そっか、Maya 2017 はPySide2だね・・・。そんな簡単には行かないか。
2、3ヶ月程前に社内ツールを2017に変換しようとして色々試していて、何日も掛けても失敗し続けていた絶望的な時に出会えた神モジュールがあります。
Qt.pyです。
なんとなくUIを作っているだけで、正直PySideとか良く理解していないですw
それでも、これを使えばなんとかなるんじゃない?と思いながら色々やってみて、ネットでサンプルを探してみたら、出来ました!
これで2015,16,17,18 は同じコードで動きます! (16と17でしか試していないけど)
Qt.py、すばらしい。

コードはこんな感じです。
#Python
from Qt import QtWidgets
from maya import cmds
class autoKeyFrameColor():
def __init__(self):
cmds.scriptJob(conditionTrue=['autoKeyframeState', self.changeMenuStyleSheetRed] )
cmds.scriptJob(conditionFalse=['autoKeyframeState', self.changeMenuStyleSheetDefault] )
def changeMenuStyleSheetRed(self):
QtWidgets.QApplication.instance().setStyleSheet("QMenuBar {background: rgb( 155, 10, 10 );}")
def changeMenuStyleSheetDefault(self):
QtWidgets.QApplication.instance().setStyleSheet("")
このモジュールを読み込んで、クラスを実行すれば良いだけです。
例:
autoKeyFrameColor.py というファイルに保存して、このファイルをMayaのScriptsフォルダに入れます。
Mayaの「userSetup.py」に
import autoKeyFrameColor
autoKeyFrameColor.autoKeyFrameColor()
を書いておけば、Mayaが立ち上がるたびにこのイベントが登録されます。
これだけで、オートキーがONと感知したら、メニューの色を赤にしてくれる。OFFにすると、元に戻してくれる。
もちろん Qt.py ファイルを Scripts フォルダに入れないと動かないですよ。
Qt.py の開発者の皆さん、ありがとうございます!
あるプロジェクトでそのプロジェクト専用のプラグインやシェーダーを使うために Maya 2016.5 とPythonの環境パスを set MAYA_SCRIPT_PATH と PYTHONPATH でバッチファイルで変えています。
他のプロジェクトも同じMaya 2016.5 を使っているので、今どのMayaが立ち上がっているかは分からなくなってしまうという問題が出てきました。プロジェクトの専用プラグインちゃんと動いているかどうかは確認すれば済む話ですが、ミスを防ぐために一見で見分けられるようにしたい。
とりあえず、-style cleanlooks などを試してみようと思いました。
こんな感じです:
C:\Program Files\Autodesk\Maya 2016.5\bin\maya.exe -style cleanlooks
使えるスタイルは:
gtk, cleanlooks, windows, windowsxp, windowsvista, macintosh, cde, motif, plastique, monolith

白っぽくて一発で違うMayaを使っているのが分かります。
しかし、見づらいな・・・。
元々のグレイバックグラウンドが残っているけど、文字が黒に変わってしまっているところが多くて、見辛い。
色設定で色々カスタマイズすればなんとか使えるようには出来ると思いますが、やっぱり元のUIのままで1ポイントだけ変えたいと思って、色々調べてみたら、QtGuiコマンドで変更が出来ました。
from PySide import QtGui
QtGui.qApp.setStyleSheet("""
QMenuBar {
background: rgb( 68, 100, 35 );
color: rgb( 225, 225, 225 );
}
""")
background は 背景の色で color は文字の色。0 ~ 255の数値で設定が出来ます。
以上のコードを実行すると、こうなります:

有効期限はそのセッションが終わるまで。
なので、Mayaが立ち上がるたびに自動的にこの色になって欲しい場合はuserSetup.py にこのコードを入れれば、毎度この色に変更されます。
因みに、userSetup.py をこのプロジェクトのMAYA_SCRIPT_PATHに入れれば、このプロジェクトを立ち上げる時だけに実行されます。
例えばプロジェクトはProjectXという名前にしよう:
- プロジェクトXのMayaスクリプトフォルダ: D:\ProjectX\Scripts
- D:\ProjectX にMaya.bat を作成する
このMaya.bat の中身は:
@set MAYA_SCRIPT_PATH = Scripts
@start "" "C:/Program Files/Autodesk/Maya2016.5/bin/maya.exe"
そして、userSetup.pyの中身は:
# -*- coding: utf-8 -*-
def changeUIColor():
from PySide import QtGui
QtGui.qApp.setStyleSheet("""
QMenuBar {
background: rgb( 68, 100, 35 );
color: rgb( 255, 255, 255 );
}
""")
changeUIColor()
userSetup.pyに色々入れているので、コードの整理と管理しやすくする為にファンクションに入れましたが、別に直下でもOK。
Maya 2011 から QtGui を使っているので、2011以降でしたら、こんな感じでUIの色は簡単に変えられます。QtGuiは色々調べれば、色々カスタマイズが出来そうですね・・・。
回転値を0にして、方向値(Orient) だけでジョイントの向きを設定しないといけない作業がありました。そして、Y軸は外側に向かせないといけない条件。
Orient Joint は 100% 合わせてくれない(ま、これを100%自動にするのは無理ですね)
?マークでピボットを回転させると Rotate Axis に数値が入ってしまうし、
普通(スクリプトなし)ではどうやって出来るのかは分からないです。
少しずつ、ペアレントを切って、方向を直して、ペアレントしなおして、なんとなーく色々いじてみると出来たりするのですが効率的に最悪です。そして死ぬほどつまらない。
物量も多いから、仕方なくスクリプトを書いてみることにした。
目的は回転を0にして、方向が変わらないようにを方向値を自動に調整。
そうすると、回転で好きな方向に向かせて、自動的に仕様に合わせられます。
で、出来たのはこれです。
Maya | Rotation To Orient (and vice versa) from myara on Vimeo.
やーつまらない動画ですね。説明もないし・・・なんか、すいません。
必要性があるかは分からないですけど、自由に使って下さい。
同じ事をスクリプトなしで出来る方法があれば、是非教えてください。
DOWNLOAD■使い方
GUIなどないです。作る予定もない。
Script フォルダに入れて、以下のコマンドでボタンを作って:
回転値0方向自動調整:
import mRotOri
mRotOri.main()
方向値0回転値自動調整:
import mRotOri
mRotOri.main(0)
---
これからはちょっとマニアックな話です。
方向が変わらないようにを方向値を自動に調整したいので、
回転値を方向値に足せばいいで。
単純に考えるとそうですが、Euler角はそのまま足すことが出来ないですね。
なので、Matrix に変換して、Matrix で足して、Eulerに戻して、Radiansから角度に戻すという流れかなと思っていましたが、OpenMaya を使えば一発で出来るとこの記事に書いてありました (英語)
http://www.akeric.com/blog/?p=1067オブジェクトの Matrix は getAttr で取得が出来ます。
しかもローカルとグローバルとインバースも。これは便利ですね。
この記事では グローバルマトリックスを使っていますが、今回はローカルの方が必要です。
このMatrix は角度値ではなく、オブジェクトの方向の角度なので、回転値を方向値に足す必要はありません。もう、このMatrix情報をDegreesに変換すれば良いだけです。それだけです。すばらしい。
流れとしては、OMのMMatrixを作って、Matrix情報をMMatrix に入れて、MTransformationMatrixに変換して、euler情報を取得という結構簡単な方法です。
単純だけど、昨日からこのツールを書いているんですね。
このMatrix情報を変換したら後は入れ替えるだけです。
回転を0にして、変換したMatrix情報を方向値として入れなおせばOK。
逆に方向値を0にして、変換した情報を回転値として入れなおすことも可能。
以上
Read more
2013 から ネームスペースエディターが出来て、簡単に削除が出来るようになりましたが、
それでも1クリックでやりたい時もあり、他のスクリプトと同時に走らせたい場合も多い為のメモです:
ネームスペースを全て取得して、
削除して、ペアレントとマージする。(ネームスペースエディターと同じ効果)
//mel
string $allNS[] = `namespaceInfo -listOnlyNamespaces`;
for ($ns in $allNS){
if ($ns != “UI” && $ns!=”shared”){
namespace -mergeNamespaceWithParent -removeNamespace $ns;
}
}
#Python
from maya import cmds
allNS = cmds.namespaceInfo(listOnlyNamespaces=True)
for ns in allNS:
if ns!="UI" and ns!="shared":
cmds.namespace( mergeNamespaceWithParent=True, removeNamespace=ns)
Next page