2016年12月7日水曜日

Photoshopのスクリプトからexeを実行したい

Photoshopの話しが続きますが・・・。

表題の通り、jsxからexeを実行したいのです。

ファイルオブジェクトにexecute()メソッドがあることはある。
ただし、引数を渡せないときた。
しかも、渡す引数は実行するたびに変わる可能性があるのです。


こんな時どうするか?
jsxからバッチファイルを作るしかないじゃないですか!


function createBatchFile( arg )
{
 const CR = String.fromCharCode(13);
 const BATCH_FILE = new File(Folder.temp+"/hogehoge.bat");
 
 var command;
 switch( arg )
 {
 case 0: command = "echo \"hoge\""; break;
 case 1: command = "echo \"hogehoge\""; break;
 }
 
 BATCH_FILE.open("w");
 // 書き込み開始
 BATCH_FILE.write("@echo off"+CR);
 BATCH_FILE.write(command+CR);
 BATCH_FILE.write("pause"+CR);
 // 書き込み終了
 BATCH_FILE.close();
 
 // バッチ実行
 BATCH_FILE.execute();
 
}

createBatchFile( 0 );
createBatchFile( 1 );


3行目のfromCharCode(13)っていうのは改行コード。
4行目のFolder.tempでPhotoshopが使用するテンポラリフォルダを取得できるので、そこへ間借りさせてもらい"hogehoge.bat"を指定しています。
7行目のswitchで記入する文字列を分岐。この部分で実際に実行するexeを指定するわけです。
13行目でファイルを開き15行目からバッチファイルに記述です。

最後、22行目でバッチの実行。

すると2回関数を呼んでいるので、DOS窓が2つ出てくるはず。


execute自体は実行終了を待ってくれないので連続実行は危険極まりない。

2016年12月5日月曜日

Photoshopで表示されているレイヤーセット名を取得する

テクスチャとか作っているとレイヤーセットが増えてきますよね~。
カラーバリエーションとか模様違いとか。

出力するときに「ファイル名+レイヤーセット名」みたいにすると便利そうです。
今画面に表示されているレイヤーセットの名称を調べようとした時、どうするのか?


単純にレイヤーセットをリスト化して、最初に出てきた可視レイヤーセット名を取得すれば良いような気がします。

getLayerSetName = function()
{
    var lsObj = activeDocument.layerSets;
    
    var result = "";
    for( i=0; i<lsObj.length; i++ ){
        if( lsObj[i].visible ) {
            result = lsObj[i].name;
            break;
            
        }
        
    }
    
    return result;
    
}


これだけだったら話は早いのですが、斜め上の行動をする人が居るのが世の常。


こんな感じでレイヤーモードと透明度で色味調整しているファイルがあるかもしれない!
ま、スクリプト側からは注意喚起することくらいできないんですけど・・・。
目的はレイヤーセット名の取得なので無視します。


ちなみに、レイヤーの取得方法は3種類。
activeDocument.artLayers レイヤーのみ
activeDocument.layerSets レイヤーセットのみ
activeDocument.layers    レイヤーとレイヤーセット

このうちactiveDocument.layersから各レイヤーのblendMode,fillOpacity,opacity,visibleなんかの状況から分岐処理させるとかかな。


レイヤーカンプ使った出力スクリプトが公式で有るからソレ使えよみたいな感じですが、
テクスチャ作成途中の段階でレイヤーカンプ作るとレイヤーカンプは壊れ易いので無理。

そもそも3Dデザイナーのフォトショッパーってレイヤーカンプの存在知らなかったりするし。

2016年12月2日金曜日

Photoshopにスクリプトを登録してみる覚書

Photoshop用の自作スクリプトをメインメニューのファイル(F) > スクリプト(R)
の欄に表示させるには、Photoshopのインストール先の Presets\Scripts へ.jsxファイル
をコピーします。

たとえば hogehoge.jsx というのを作成しコピーした場合

ファイル名で登録されました。

よくあるパターンとして、メインになる処理を hogeCore.jsx にまとめて、引数だけ変えた
呼び出し用スクリプト hogeA.jsx と hogeB.jsx を作って登録したいと思った時、普通に
Presets\Scripts へコピーすると・・・



3つとも表示されてしまいます。

hogeCore はメニューに出したくない場合はどうすればよいか?


Presets\Scripts の中を見てみると、~Scripts Only みたいなフォルダが見つかります。
試しに"hoge Scripts Only"とフォルダを作成し、そこへ hogeCore.jsx を移動します。
すると、



hogeCore.jsx がメニューに表示されなくなりました。



次に、呼び出しファイルから処理ファイルを呼び出すスクリプトの書き方。

function main()
{
    const SELF = File( $.fileName );
    
    $.evalFile( SELF.path+"/hoge Scripts Only/hogeCore.jsx" );
    
    var ret = hogeCore();
    alert ( ret );
    
}

main();


function hogeCore()
{
    alert ("hogehoge");
    return 0;
    
}



$.fileName で自分のファイル名をフルパスで取れます。
$.evalFile() は、指定されたファイルを読み込む処理。
ここで hogeA.jsxと同じ階層の hoge Scripts Only フォルダ内に在る(はずの)hogeCore.jsx
を読み込んでいます。

こうすることで hogeCore.jsx の hogeCore() が実行可能になります。


メニューから hogeA を実行すると、

まず hogeCore.jsx のアラートが表示され、


hogeCore の返り値がアラートされます。


2016年11月24日木曜日

Freeze Transformations その2

今回もまた、おもむろにspaceLocatorを作成して適当に移動・回転・拡縮します。

で、Modify から Freeze Transfomations を実行。



ピボットが原点へ移動し、Translate は shape の Local Position に変化。
rotateとscaleが何処へ行ったかは謎です。


ロケータのフリーズで注意しないといけないのは、階層構造になった時。


こんな感じに階層構造になっていた場合、子の locator2 ほうをフリーズすると、


ピボットが親の位置に移動しますが、親の locator1 をフリーズすると、


子の locator2 のピボットも原点に移動してしまいます。
せっかく階層に配置したのにフリーズかけてしまいグチャグチャみたいな事になりがち・・・。

Reset Transfomations と Freeze Transfomations を間違えたのか、酷い構造のデータを見た事があります。
自分ではこんなデータを作らないように注意しときたいですね。


ただ、このフリーズ機能、アニメーションさせる前限定の機能。
アトリビュートにアニメカーブが接続されているとフリーズ実行時に

// Error: Freeze Transform was not applied because locator1.scaleX has incoming connection. //

みたいな事になります。

2016年11月14日月曜日

Freeze Transformationsその1

なんかチャネルボックスの数値がゼロになるような機能です。

まずは、選択オブジェクトのピボットが見えるよう設定を変更します。


初期状態では Off になっているので On に。
これで選択したオブジェクトのピボットが表示されるようになります。
リガーであれば表示させておくことをオススメ。

ピボットの見た目はこんなん。



おもむろにpolyCubeを作成して適当に移動・回転・拡縮します。


変形が分かりやすいようにlocalAxisを表示しています。
※メインメニューの Display -> Transform Display -> Local Rotation Axes

こんな感じのオブジェクトに Freeze Transform を実行するとこうなります。


この機能が実行されるコマンドは makeIdentity というもの。
メニュー名と一致していないのですがコマンド名から大体の処理内容が予想できますね。

フリーズ前のこんなマトリクスが
-----------------------------
x: 0.1440 -0.0708 -1.1282 0
y: 0.3970  1.1363 -0.0206 0
z: 0.8128 -0.2818  0.1214 0
t: 1.1656  2.5396  0.0000 1
-----------------------------

フリーズ後、このようになります。
------------
x: 1 0 0 0
y: 0 1 0 0
z: 0 0 1 0
t: 0 0 0 1
------------

オブジェクトのマトリクスが単位行列になってしまいました。


バインドする場合は、更に Reset Transform を実行します。


すると、ピボットが原点に移動したように見えます。
※実際は親オブジェクト基準の位置になります。

こうしておかないと、エンジンによってはピボットの差を加味してくれない場合があるので、
頂点が想定の位置とズレてくる事があります。


ちなみに、フリーズする前にリセットを行うと・・・

トランスフォームの変形がリセットされるだけなので、順番は重要。
なんとなく使ってもらわれると困る機能の一つです。