表計算

表計算で1週を行ごとに表記したい時‥‥

 

2020/05/04〜2020/05/10

2020/05/11〜2020/05/17

2020/05/18〜2020/05/24

2020/05/25〜2020/05/31

2020/06/01〜2020/06/07

2020/06/08〜2020/06/14

2020/06/15〜2020/06/21

2020/06/22〜2020/06/28

2020/06/29〜2020/07/05

 

‥‥というのを、まさか、1行ずつ手書きで書き込むようでは、表計算コンピュータプログラムを使っている意味がないです。

 

たかだか、週の期間の表記ですが、「表を計算するコンピュータ」の機能を活用したいですネ。

 

 

 

定数として基点となる日付「DATE(2020,5,4)」を決めたら、以下のように、行番号で自動計算するように仕込めます。

 

DATE(2020,5,4)+(7×(ROW()−2))&"〜"&DATE(2020,5,4)+(7×(ROW()−1)−1)

 

表計算の式は、変数も使えないし改行もできないので読みにくいですが、とりあえず、これで自動で行ごとに1週で更新されます。

*ヘッダ行を考慮して、2行目から計算する仕組みです。

 

月ごとに比べて、1週は必ず7日なので、計算が楽です。

 

もっと、スマートな方法があるかも知れませんが、コロナウィルスの集計表はこうして作っております。

 

 

 

表計算のNumbersやExcelやGoogleスプレッドシートは、作表ソフトではなく、表計算ソフトなので、計算を組み込んで本領を発揮します。

 

個人規模の小規模な集計表でも、表計算の計算式をバンバン使いましょう。そうすれば、いつしかプログラムやスクリプトを常用する感覚に慣れます。

 

 


タイムシートの枚数を組み込む

作画作業でも時間表記は必要です。

 

だからと言って、前回書いたのと同じく、タイムコードを1スタートにするのはトラブルの元なので避けねばなりません。

 

何よりも、ぶっちゃけ、タイムコードで1スタートにしているのは、経験の幅が狭い状態を晒しているようなものなので、かっこ悪いです。

 

タイムコードはタイムコード。タイムシートはタイムシート。コマ番号はコマ番号。

 

別に扱えば良いです。

 

 

 

前回紹介したテキストレイヤーとエクスプレッションによる各種時間表記を、アニメの作画用途に改造しましょう。

 

アニメーターでAfter Effectsを併用している人は少ないとは思いますが、未来のアニメーターはコンポジットにも関わって、あらゆる作画要素をコントロールしたほうが良いですから(表現面でもコスト面でも)、After EffectsのTIPSとして紹介します。

 

After Effects内部の小数点付き秒数を、まずはタイムコードに変換します。ついでに、fpsも取得しておきます。

 

fps=1/thisComp.frameDuration;

tc=timeToTimecode(t = time + thisComp.displayStartTime, fps, true);

 

秒数は、単純に秒の小数点を切り下げた数字で取得します。

 

sec=String(Number(Math.floor(time)+1000)).slice(1);

 

1秒間のコマ番号は、タイムコードのフレーム番号から、取得して1を足すだけです。せっかくタイムコードを変数「tc」に格納したので、利用するわけです。JavaScriptの「暗黙の型変換」ではなく、お行儀よくString()やNumber()で明示的に、文字と数を相互に変換しています。

 

koma=String(Number(tc.split(":")[3])+101).slice(1);

 

1を足すのに、101を足しているのは、表示上の桁数を揃えるためです。01は数値では1になるので、先頭の0を保つために、「101という文字の2文字目以降を取得」するのです。

 

"101".slice(1);

 →"01"

 

After Effectsの時間をフレームにするには、小数点付き秒数から地道に算出する方法もありますし、タイムコードの各桁から算出する方法もありますが、After Effectsビルトインの「timeToFrames()」が手っ取り早いです。

 

komaNumber=String(Number(timeToFrames(t = time + thisComp.displayStartTime, fps, true))+100001).slice(1);

 

 

さらに、どうせなので、何枚目のタイムシートでも読みやすく表記をプラスしましょう。

 

10+9コマって、2枚目の6秒シートの何秒何コマ目でしょう? 2枚目の6秒シートの通し番号の何コマ目でしょう?

 

まずタイムシートには、3秒シートや6秒シートがありますので、タイムシートの長さを定義します。

 

sheetLength=144;

 

144はお馴染みの数字ですね。6秒シートです。

 

この「sheetLength」で、タイムシートの秒と通しのコマを割れば良いです。

 

currentSec=Number(sec)%(sheetLength/fps);

currentKomaNumber=String(Number(komaNumber)%sheetLength+10000).slice(1);

 

さらに現在のタイムシートが何枚目かも計算しておきましょう。シートは「0枚目」と言う呼び方はしないので、二桁に揃えつつ1を足しておきます。

 

currentSheetNumber=String(Math.floor(time/(sheetLength/fps))+101).slice(1);

 

以上で、時間の情報取得は終了です。

 

あとはまとめて表示‥‥ですが、情報量が多いので、改行を混ぜましょう。

 

tc+"¥r"+sec+"+"+koma+" | "+currentSec+"+"+koma+"["+currentSheetNumber+"]¥r"+komaNumber+" | "+currentKomaNumber+"["+currentSheetNumber+"]";

 

 

以上を、テキストレイヤーのソーステキストのエクスプレッションに書き込みます。

 

//基本設定

sheetLength=144;

fps=1/thisComp.frameDuration;

 

//基本情報

tc=timeToTimecode(t = time + thisComp.displayStartTime, fps, true);

sec=String(Number(Math.floor(time)+1000)).slice(1);

koma=String(Number(tc.split(":")[3])+101).slice(1);

komaNumber=String(Number(timeToFrames(t = time + thisComp.displayStartTime, fps, true))+100001).slice(1);

 

//タイムシートの複数枚に対応

currentSec=Number(sec)%(sheetLength/fps);

currentKomaNumber=String(Number(komaNumber)%sheetLength+10000).slice(1);

currentSheetNumber=String(Math.floor(time/(sheetLength/fps))+101).slice(1);

 

//結果表示

"TC "+tc+"¥r"+sec+"+"+koma+" | "+currentSec+"+"+koma+"["+currentSheetNumber+"]¥r"+komaNumber+" | "+currentKomaNumber+"["+currentSheetNumber+"]";

 

以下のように映像に表示されます。

 

 

 

タイムコードはいつもの0スタートの「00:00:00:00」表示。

 

タイムシートの表記は、カット全体の000+00書式(999秒まで対応)と通し番号の00000書式(99999コマまで対応)の他に、タイムシート何枚目の「何秒何コマか」「通し番号何コマ目か」を表示します。

 

まあ、ありえないでしょうけど、シートは99枚まで対応してます。‥‥表示が2桁なので。

 

これで、全体の時間位置と、タイムシート何枚目の時間位置も表示されます。

 

上の映像をみれば、左側は秒数が6秒後もどんどん加算されますが、右側は0秒に表示リセットされます。

 

こうした仕組みが、ユーザのスクリプト(エクスプレッション)でいくらでも自作できるのは、After Effectsの強みです。

 

クリスタにもこうした機能=エクスプレッションやスクリプトがあれば良いのにネ。

 

 

 

 


splitとjoinとsliceで。

文字列から任意の部分を取り出す際に、その文字列に規則性がある場合は、JavaScriptのスプリットとジョインとスライスでほとんどのことが可能です。

 

例えば、

 

XY08_055_T1

 

から、T=本撮を表す文字を取り出す場合は、

 

"XY08_055_T1".split("_")[2].slice(0,1);

 

‥‥で可能です。

 

xy_08_055_t1

 

から「t」を取り出すなら、

 

"xy_08_055_t1".split("_")[3].slice(0,1);

 

です。

 

charAt()を使うのも良いですが、sliceだけでも可能です。

 

テイクの後の数字を取り出す場合は、それぞれ、

 

"XY08_055_T1".split("_")[2].slice(1);

"xy_08_055_t1".split("_")[3].slice(1);

 

です。sliceは範囲指定も「以降全部」も可能なので、色々と使えるのです。

 

ちなみに、文字を1文字ずつバラバラにしたい場合は、

 

"XY08_055_T1".slice("");

 

‥‥で可能です。私はこのあたりの知識はAppleScriptから流用しました。「AppleScript's text item delimiters」というヤツです。1つの言語をつっこんで習得すると、別の言語でも応用が可能になりますヨ。

 

 

 

アンダースコアを日本語の接続詞「の」に変えたい場合は、それぞれ、

 

"XY08_055_T1".split("_").join("の");

"xy_08_055_t1".split("_").join("の");

 

これは、「変換」しているのではなく、一旦アンダースコアで分解したのちに、「の」という文字で連結しているのです。

 

XY08の055のT1

xyの08の055のt1

 

この方法を転用すれば、変換にも使えます。‥‥AppleScriptでは常套手段ですが、JavaScriptでも可能です。

 

"今日の三鷹は雨です。".split("三鷹").join("高円寺");

結果:"今日の高円寺は雨です。"

 

普通はreplaceを使うでしょうが、こういう方法もあります。

 

なので、ファイル名から拡張子だけを除外したい時にも使えます。

 

XY01.03.128.T1.MOV

 

なんていう名前(まあ、こういう名前はないですけどネ)は、普通にドットで区切ると、拡張子の.MOV以外も全てバラバラに分解されちゃいますが、

 

XY01, 03, 128, T1, MOV

 

「.MOV」で区切れば、ファイル名のカット名部分だけを取り出せます。

 

"XY01.03.128.T1.MOV".split(".MOV")[0];

結果:"XY01.03.128.T1"

 

"XY08_055_T1.mov".split(".mov")[0];

結果:"XY08_055_T1"

 

 

 

大文字小文字が混在していて、いちいち分割する文字列の条件を変えなければならない場合は、いっそのこと、全て大文字か小文字に変換したあとで処理するのも手です。

 

"XY08_055_T1.mov".toUpperCase().split(".MOV")[0];

結果:"XY08_055_T1"

 

 

 

いずれの場合にせよ、事前の「名前の規則」が整然と規定されていることが必須です。

 

そして、人間の目視による運用と、プログラムにおける処理の利便性の、両方をいい感じで兼ね備えた名前を規定できれば、ベストですネ。

 

私の思想だけで言えば、作品、話数(パート)、カット番号、種別、バージョン番号は、全て同じ文字列で分割していたほうが、人の目にもコンピュータの処理にも、両方に優しいと思います。

 

xy_01_001_vfx_t2

zz_a_032_gen_t1

→ 頭から順に読んでいけば、命名規則を詳しく知らなくても、内容が伝わります。

 

でもまあ、まずは整然とした名前の規定をおこなうことが先決です。

 

しかし、今のアニメ制作現場は、名前の規定すら曖昧で、各セクションが別々の規定で運用するほど、連携が希薄です。

 

中々、未来のオンライン運用への道は険しい‥‥ですネ。

 

 

 


連想配列を使おう

アニメ業界の撮影さんのエクスプレッションは、ifやmatchは使う一方で、連想配列はあまり活用していません。

 

this_comp‥‥という表記を最近見かけましたので(現在はthisComp)、相当古いバージョンのAfter Effectsからエクスプレッションを受け継いでいることもありましょう。

 

私もそうでしたが、言語を覚えたての頃は、結構まわりくどい書き方をしているものです。

 

JavaScriptの場合、いちいち「何らか==trueだったら」「何らかが0以外ならば」という書き方をしなくても、「何らかだったら」というシンプルな書き方でOKです。

 

AppleScriptは明確に真偽値でない場合はNGですが、JavaScriptは、false、0、""、以外は真とみなされるので、書き方が短くて済みます。

 

2020年になった今、雛形を点検して整頓してみるのも良いですヨ。

 

 

 

「何撮か?」というボールドの表示で、今でもifを見かけます。

 

ifで延々と改行して条件分けする方法は、初心の頃にはやりがちです。

 

例えば、「XY」という作品略号で、

 

XY04_012_T2 → 作品「XY」4話 Cut12 本撮テイク2

XY11_201_K1 → 作品「XY」11話 Cut201 タイミング撮テイク1

 

‥‥という書式の場合、撮影の種別を示すTやKなどを、コンポジション名から取り出す流れは、

 

compType=thisComp.name.split("_")[2].charAt(0);

 

‥‥のようになりましょう。

 

TやKやSを「何撮」という文字列に関連づけて生成する際に、ifを使うと、

 

if(compType=="T"){

typeText="本撮":

}else if(compType=="K"){

typeText="タイミング撮":

}else if(compType=="S"){

typeText="線撮":

}else if(compType=="Y"){

typeText="予告":

}

 

‥‥となりますが、何回もelse ifやtypeText=を書くのは、正直、野暮ったいです。

 

なので、連想配列の出番。

 

typeList={T:"本撮",K:"タイミング撮",S:"線撮",Y:"予告"};

 

‥‥のような連想配列を記述して、キーワードで呼び出します。

 

typeList[compType];

 

ifとelseに比べて、たったの2行で済みます。

 

typeList={Y:"予告",S:"線撮",K:"タイミング撮",T:"本撮"};

typeText=typeList[compType];

 

 

if文より明解で簡潔、メンテもしやすいです。

 

もし「何撮」かが増えた場合は、連想配列の内容を増やせば良いだけです。elseで行を増やすより、扱いやすいです。行をスクロールせずに1行で判読できます。

 

 

 

連想配列を複合化して、辞書のようなものを作ることもできます。

 

typeDic={T:{jp:"本撮",en:"FINAL",summ_jp:"本番撮影",summ_kana:"ファイナルテイク",sect:"撮影工程",cont:"撮影工程における本番素材を用いた作業"};

 

Tというキーワードで、本撮にまつわる様々な情報を引き出せます。‥‥まあ、ここまで細かくする必要はないでしょうが、一例として。

 

typeDic[T][sect];

=結果は「撮影工程」

 

typeDic[T][cont];

=結果は「撮影工程における本番素材を用いた作業」

 

‥‥まあ、ここまで凝る必要もないとは思いますが、ifしか使わない時に比べて、格段にできることが広がります。

 

 

 

連想配列‥‥という言葉の「響き」は、聴き慣れないので難しく感じますが、要は「ラベル付きのリスト項目」です。

 

無作為に箱の中に詰めるより、1つ1つにラベルを貼っておけば、判別しやすくなって取り出しやすくなりますよネ。

 

聞けば「なんだ、そんなことだったのか。日常生活でも普通にあることだね。」と納得できることなんですが、「連想配列」などと言われるとなんだか難しく感じます。

 

クラス型オブジェクト、インスタンス、インヘリタンス‥‥とか聞くと、「ちんぷんかんぷん」と敬遠しがちです。

 

しかし、「型をあらかじめ作る」「型から実体を作る」「違う型を作る際に、元の型から要素を継承する」と言われれば、「あー、あるよね、そういうやり方」と思えるわけです。

 

プログラムは、「難しげな用語」に怖気付いたら負けです。

 

難しげな用語を、どういう意味か調べれば、さほど怖くはありません。恐ろしく難解な物事だったら、こんなに世界中にプログラマなんて溢れていませんよネ。

 

アニメ制作だって同じです。「密着マルチ」「付けパン」なんて聞くと、何のことか部外者はわかりませんが、現場で用語の意味と内容を知れば、普通に扱えるようになります。

 

言葉の響きに物怖じするなかれ。

 

 

 

連想配列は、エクスプレッションでも自動処理でも使えます。

 

Adobe CCなら、PhotoshopやAfter Effects、macOSなら様々なAppで、活用可能です。

 

JavaScriptに限らず、他の言語でも、「キーとバリュー」、つまりキーワードと項目の内容を関連付けるリスト(配列)は用意されていますので、考え方さえ覚えたら、様々に応用できるようになります。

 

 


ミュージック(旧iTunes)の曲の時間合計・2

今さらAppleScriptを覚える気にはなれない。‥‥まあ、そうですよね。私は20年以上AppleScriptを使い続けていますが、2020年の今なら、そう思います。

 

なので、JavaScript。

 

前回書いたAppleScriptによるスクリプトは、JavaScriptで同じことが記述できます。内容を翻訳できます。

 

実はAppleScriptのエディタは、言語を切り替えてJavaScriptでも書けるんです。

 

 

 

After Effectsのエクスプレッションや自動処理でおなじみの書式が通用します。

 

なので、Music.appの選択項目の合計時間を表示するスクリプトはJavaScriptとAutomatorで作ったほうが、今は実用性があるでしょうネ。

 

クイックアクション書類を作って保存すれば、ミュージックの「サービスメニュー」に自作のアクションがリストされます。

 

 

 

 

「JavaScriptを実行」を追加して、JavaScript文を書きます‥‥が、なんだこれは。

 

エディタ部分の配色がまっくらで読めませんネ。

 

なので、スクリプト文を以下に。ただ実行するだけなので、入力もパラメータも不要です。

 

function run() {

    

var app=Application("Music");

app.includeStandardAdditions=true;

var w=app.windows[0];

var td=0;

for(var i=0;i<w.selection().length;i++){

td=td+w.selection()[i].duration();

}

app.displayDialog((Math.floor(td/60))+"分"+(Math.round(td%60))+"秒");

return true;

}

 

 

曲の時間(duration)は秒単位(小数点付き)で扱うので、単純に足した後で読みやすいように整形すれば良いです。何のヒネりもないシンプルな内容なのは、前回と同じ‥‥というか、前回のAppleScriptの内容をJavaScriptに翻訳しただけなので、includeStandardAdditionsなどの独特な追加部分以外は、書き方の作法こそ違いますが内容は同じです。

 

for文とか、Math.floorやroundは、After Effectsのスクリプトでもおなじみですネ。

 

After Effectsでエクスプレッションやスクリプトを覚えておけば、ミュージックにも応用できる‥‥というわけです。

 

まあ、alertではなく、displayDialogだったりと、癖は多少ありますが、基本的な書式はいつものJavaScriptでOK。

 

制御について知りたい人は、英文だけどコレを読めば大体概要は掴めます。

 

OS X 10.10 Release Notes

https://developer.apple.com/library/archive/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/OSX10-10.html#//apple_ref/doc/uid/TP40014508-CH109-SW1

 

 

 

スクリプトやプログラムを覚えておけば、「性能としては存在するのに、表立った機能として存在しない」、コンピュータのポテンシャルを引き出せます。

 

曲のそれぞれの秒数を合計する‥‥なんて、コンピュータができないわけがない‥‥のに、機能として存在しなければ、分単位までしかユーザは情報を取得できません。

 

‥‥それとも、電卓で手作業で各曲の合計秒数を算出します?‥‥いやいや、そんな無駄な時間は人生がもったいない。

 

PhotoshopやAfter EffectsのJavaScriptに馴染んだら、他でも応用が効くようになりますから、まだスクリプトに着手していない人はチャレンジすることを強くお勧めします。

 

 


ミュージック(旧iTunes)の曲の時間合計

ミュージック.appで、プレイリストの細かい秒数まで知りたい場合、どうすれば良いんでしょう。何か、秒数まで表示できるオプションがあるでしょうか?

 

あるかも知れませんが、私は知らないので、スクリプトでちょちょいと処理します。

 

以下のAppleScriptを実行すれば、現在選択中の曲(トラック)のデュレーション合計がわかります。

 

 

スクリプト文は以下。

 

tell application "Music"

    set td to 0

    tell front window

        repeat with i in selection

            set td to td + (duration of i)

        end repeat

    end tell

    display dialog ((td div 60) as text) & "分" & ((td mod 60) as integer as text) & "秒"

end tell

 

 

 

現在表示されているウィンドウの選択項目を順々に調べて、曲の時間を集計します。凝ったところは何もない、シンプルなスクリプトですネ。

 

AppleScriptがわからなくても、文面を読めば、なんとなくでもやっていることが解りますよネ。

 

 

 

これで90分カセットの片面にギリギリ入る合計時間を調整できます。もちろん、曲のチョイスは手作業ですけどネ。

 

片面45分だからといって、44分でプレイリストを組むと、最後の曲が終わった後で、最大で2分の無音が続きます。実際の片面の長さは46分くらいなので、曲が終わったらすぐにテープを巻ききってパタンと再生が終わるように組むと、快適ですヨ。

 

 


JavaScript(JS)、Adobeのエクスプレッションやスクリプトは、型の変換をうまいこと自動で処理してくれます。

 

型とは、

 

数値としての100

数字としての「100」

 

‥‥というように、一見同じに見えますが、カテゴリー・種別が違うことです。(なんか、雑な表現ですまんス)

 

数値として100+100なら200ですが、数字(文字)としての「100」+「100」は「100100」です。

 

初心の頃は、こうした「型の認識」が曖昧で、プログラム言語が提供する「暗黙の型変換」に甘えきっているので、自分の書いたプログラム文がうまくいかない時は理由が分からずパニックになります。

 

000+1が0001にならないよ! どうやっても1になっちゃうよ!

 

‥‥というのは、数値でプラスしているからです。

 

フレームナンバーは数値ですが、表示するときに文字にしたいのなら、丁寧に書けば、

 

"000"+String(1);

 

‥‥という書き方になります。String()を省いても暗黙のうちに型を変換してくれるので、

 

"000"+1

 

‥‥でも結果オーライです。文字列の"000"と連結した時点で、1は"1"にキャスト(型変換)されます。ありがとね、JS。

 

 

 

私が20年前に常用していたプログラム言語では、変数を使う時に必ず型を決めなければなりませんでした。たしか‥‥

 

Dim frameNumber as integer

 →意味:整数としての変数frameNumber

 

‥‥のような感じだったと思います。「今から取り扱おうとする値は、どんな型なのか」を宣言する必要がありました。つまり、御膳立てに時間がかかって、本題に入るまでが長かったのです。本格的なAppを作るのならともかく、ささっと自動処理したいニーズには向きませんでした。

 

それに比べれば、JSはヌルヌルのユルユルのズルズル。賢く使えば便利ですが、無自覚に使うとトラブルの元にもなります。

 

 

 

型の相違でありがちなのは、配列のインデックスによる取り出しです。

 

["A","B","C"]=配列「A,B,C」を、例えばスライスなどで1つだけ(例えば1番目だけ)を取り出した結果は、"A"=文字列ではなくて、["A"]=配列です。‥‥これ、JSを使っていると、結構忘れがちです。

 

多くの場合は言語環境側で、文字列に自動でキャストしてくれますが、なんらかの理由でキャストが機能しない場面では構文チェックにひっかかり、エラーで先に進めなくなるのです。型にギチギチの言語なら注意してプログラム文を書きますが、JSだとついつい甘えてユルくなりがちです。

 

 

 

型を自覚して扱うようになると、例えば350の桁数を、99より大きくて1000より小さいから3桁‥‥なんてしなくても、

 

String(350).length;

 

‥‥で、桁数が簡単に取得できます。

 

JSは、型とか特に意識しなくても、ネットで書き方を見て真似して覚えられる、非常に敷居の低い言語です。しかし、JS自体がユルくいいかげんに作られているわけではなく、できるだけプログラム言語にありがちな作法を意識しないで書けるように工夫されているのです。

 

なので、IF文やループ文などの基本的な書き方をなんとなく覚えたら、

 

型の扱い

オリジナルのファンクション(関数・ルーチン)

 

‥‥を覚えていけば、いきなりハードルが上がる感じもせずに、徐々にミラクルな処理ができるスクリプトを書けるようになってきます。正規表現とかは必要に応じてちょっとずつで良いと思います。

 

 

 

プログラムは頭の柔軟な20代から始めるのが良いです。10代ならなおさら良いですが、それは各人の自由で。

 

50代からは結構難しいようには思います。でも、もしかしたら、50代で通常業務の技術的余裕ができて、空いた時間に覚えれば、案外覚えられるかも知れません。

 

アニメーターって、実はプログラムの習得に向いているとも感じますしネ。

 

だって、人間の芝居や自然現象を、線画という言語を使って、カットという1つのプログラムに仕上げているわけでしょ。

 

まあ、中には理屈など全く意識せず感性だけで描く人もいましょうが、技量の確かな人なら、個人の中でなんらかの「絵を描く言語体系」が出来上がっていて、オーダーに合わせて構造的に組み立てているでしょう。実は凄いプログラム能力なんすヨ。

 

演出上の前後の流れを把握する能力、レイアウトの構成能力、動きの観察力、情報を線画として要約する能力、状況に応じて現実と空想を織り混ぜるバランス感覚。‥‥凄いプログラム能力ですよね、改めて列記すると。

 

今回の「型」の扱いに関しても、アニメーターなら、動きやフォルム、影の付け方など、描写しようとする対象の「型」を観察して把握し、分別して描きますよネ。

 

自然現象クラス>流動エフェクトクラス>水クラス

 属性:スケール(水溜りか津波かなどの大きさ)

 属性:不純物含有度(水に土砂などの不純物がどれだけ混入しているか)

 属性:ベロシティ(動きのエネルギーの強さ)

 属性:エクストラ(エネルギーの指向性のバラつきによる水の拡散ランダム度)

 属性:発泡度(空気を巻き込んだ量)

 属性:etc,etc...

 

プログラム風に表現しましたが、水のエフェクト作画をするなら、普通に考える内容です。

 

アニメーターなら、コンピュータプログラムはできると思うんですよね。ただ、なかなかやろうと思う機会がないだけで。

 

まあ、興味が湧いたら、まずはPhotoshopのスクリプトを作って、地道なPhotoshop事務作業を自動化してみても良いですネ。

 

 

 


IFからステップアップ

エクスプレッションにせよ、スクリプトの自動処理にせよ、プログラム文を学んだ最初のうちは、IF文に頼りがちです。

 

例えば、数字の桁を4桁で揃える方法の場合、IF文を使うと以下のようになります。

 

もし、10未満だったら、

 000を数字の先頭に追加する

あるいはもし、100未満だったら、

 00を数字の先頭に追加する

あるいはもし、1000未満だったら、

 0を数字の先頭に追加する

でなければ

 そのまま

以上

 

After Effectsのテキストレイヤーのソーステキストにエクスプレッションで表現すると、

 

var frameNumber=timeToFrames(time, 1.0 / thisComp.frameDuration,true)+1;

if(frameNumber<10){

 "000"+frameNumber;

}else if(frameNumber<100){

 "00"+frameNumber;

}else if(frameNumber<1000){

 "0"+frameNumber;

}else{

 frameNumber;

}

 

 

一見、これで良いように思います。ちゃんと期待した通りに動作しますしネ。

 

しかし、長い。

 

文が長くて、変更しにくいです。

 

もし、5桁の「00001」にしたい場合、文の各所を直さなければなりません。面倒です。

 

IFを使うと、読解の時間が長くなり、メンテしにくくなる傾向があります。

 

以下の2行で、IFを使わなくても、桁数は簡単に揃えられます。

 

var frameNumber=timeToFrames(time, 1.0 / thisComp.frameDuration,true)+1;

String(10000+frameNumber).slice(1);

 

 

 

2行であっさり終了。

 

「10000」の先頭1文字を削れば、「0000」になりますから、slice(1)、つまり1文字目の後から切り取れば、容易に4桁にできます。

 

桁数を5桁にしたければ、10000を100000に変更するだけです。IF文を数行に渡って書き換えるより、かなり楽です。

 

なんなら、自動で桁数まで設定できます。4桁にしたければ、10^4(結果は10の4乗=10000)と書けば良いので、総数を文字列化して文字数をカウントすれば、自動桁揃えが可能になります。

 

10^(String(総フレーム数).length); ‥‥という感じで。

 

IFをどうしても使わなければならない場面はあります。簡単に済ませる方法があるのなら、無闇にIFを使わず、他の方法で処理するのが良いです。

 

 

 

コンポ名からボールド表記を自動生成するのも、IFに頼らず可能です。

 

例えば、「ANIMEの01話、カット001、線撮テイク1」を、以下のような命名規則にしている作品があったと仮定します。

 

ANI01_001_S1

 

「_」アンダースコアのデリミタ(文字列を区切る文字)によって、カットの名前に含まれる各情報が区切られています。作品略号と話数の間にデリミタがないのが厄介ですが、そこはおいといて、何撮のテイクなのかを、IFありとなしの2種類の方法で取り出してみましょう。

 

Cはコンテ撮、Sは線撮、Kはタイミング撮、Tは本撮

 

IFを使うと、文が数行に渡って長くなり、メンテしにくくなります。

 

var cutName=thisComp.name;

var compType=cutName.split("_")[2].split("")[0].toLowerCase();

if(compType=="c"){

 "コンテ撮";

}else if(compType=="s"){

 "線撮";

}else if(compType=="k"){

 "タイミング撮";

}else if(compType=="t"){

 "本撮";

}else{

 "不明";

}

 

もし「XX撮」が増えた場合、どんどんIFを増やす必要があります。略字に変更があった場合もめんどくさいです。

 

IFを使わず、連想配列で処理すれば、メンテしやすく、読みやすくもなります。

 

var cutName=thisComp.name;

var compType=cutName.split("_")[2].split("")[0].toLowerCase();

var compTypeList={"c":"コンテ撮","s":"線撮","k":"タイミング撮","t":"本撮"};

compTypeList[compType];

 

しかし、このままだと、「存在しない略字」の場合、「不明」が表示されません。カット名の異常には気付きますが、せっかくなので「不明」と明記しましょう。

 

そんな時こそ、あえて、IFの出番です。

 

var cutName=thisComp.name;

var compType=cutName.split("_")[2].split("")[0].toLowerCase();

var compTypeList={"c":"コンテ撮","s":"線撮","k":"タイミング撮","t":"本撮"};

 

if(compType in compTypeList){

 compTypeList[compType];

}else{

 "不明";

}

 

 

略字がリスト(連想配列)に存在しない場合は「不明」を返すようにできます。

 

キーとバリュー、つまり、略字と関連づけた文字列を記述すれば、いくらでも「何撮」の種類を増やせて(あまり増やしたくないけどネ)、略字の変更にも1行で柔軟に対応できます。IFで数行に分けて連ねるよりも、1行で見渡せるので、内容把握や修正も楽になるわけです。

 

 

 

 

IFは、まさに「IF分岐」するので、読みにくくなります。分岐してるものを追うのって、面倒ですよネ。

 

IFを使わないことで、分岐が減り、読みやすくメンテしやすいプログラム文になります。

 

ある程度、スクリプトに慣れてきたら、IFを使わない方法にチャレンジすると、コンピュータをもっと理解できて、新たな運用のアイデアにも繋がります。

 

After Effectsの雛形を共通にして、作品ごとの命名規則や運用をデータベースサーバから取得して適用する‥‥なんていうことも可能になります。

 

 

 

記事文中のスクリプト文を補足しますと‥‥

 

文字列をデリミタで分割するsplit()は、引数に""を指定すると、"ABC" を ["A", "B", "C"]に1文字ずつ分割できます。substrとかを使わなくても、何番目の文字かを指定して取り出せます。

 

また、ケアレスミスで多いのが、大文字小文字の混在です。略字をちゃんと処理できるように、大文字か小文字かに変換すると「T1」も「t1」も正常に処理できます。

 

 


ESTKの代わりに

アドビのエディタ「ExtendScript Tool Kit」=ESTKは、After EffectsやPhotoshopの自動処理を書く時に重宝してました。

 

‥‥が、最近、CCのラインアップから外れました。配布中止するなら、次のエディタを出してくださいよ、アドビさん‥‥。ユーザは、サブスクリプション代金を一生懸命払ってるんだからさ‥‥。

 

‥‥と恨み節を吐いても事態は進展しないので、「mi」でもスクリプトを書いて実行できるように、ちょっとひと工夫。

 

mi

https://www.mimikaki.net

 

 

miから、直接After Effectsにスクリプトを実行したい場合は、毎度のAppleScriptで。

 

tell application "mi" to set txt to content of front document

 

tell application "Adobe After Effects 2020"

    activate

    DoScript txt

end tell

 

5行のスクリプトですが、これで、miで書いた内容を、After Effectsに送って実行できます。miのツールバーから呼び出して実行できるようにしておきます。

*自分のアカウントのLibrary/Application Support/mi/mode/NormalまたはJavaScript/toolbarの中に、適当な名前のフォルダを作ってスクリプトを入れておきます)

 

 

 

*ちなみに「構文チェッカー」とは、JavaScriptの構文ではなくて、私が独自に規定したTS(タイムシート)記述式の構文チェッカーです。‥‥ほんとに、いろいろなことを30代にはチャレンジしましたわ。

 

 

 

 

とりあえず、これでしのいで、Adobeスクリプトを書きます。

 

 

 

ちなみに、私がJavaScript上でシングルクォートばかり使うのは、AppleScriptに移植する際にダブルクォートとバッティングさせないための習慣です。

 

DoScript "alert("Hello, World.");"

 

‥‥なんて、エラーが出るのがわかりきってますよネ。

 

いちいち、エスケープしないで済むので、昔から「スクリプト on スクリプト」の場合は、使い分けてます。

 

 

 


復活の日。

4KHDRだカットアウトだと言っても、まだまだ旧来枠の仕事の依頼はそれなりにあります。

 

一方、2000年代に夢中になって作ったxtools=コンポジットの作業をアシストする自動化ツール群は、2010年代にアニメの撮影をあまりしなくなったこともあり、メンテがおろそかでmacOS "Catalina"になった現在に正常に動くのか、非常に危うい状態です。

 

一番昔の更新日を見ると2006年だもん。‥‥まあ、中身は差し代わっていますが、それでも一番新しいツールの更新日ですら2016年で終わっています。新しいOSで動作しなくなったのを、コンパイルしなおして書き出しただけの更新です。El CapitanとかSierraの時代で止まっています。

 

今後の動向を鑑みるに、今から一生懸命になってアニメ撮影の自動化ツールを再構築するよりも、必要最小限の自動化ツールを延命措置して、2020年代の主力は4KHDRでハイブリッド(従来作画と新方式の)の運用技術の確立に据えたほうが良いのは明白です。

 

昔ながらのアニメのコンポジットの段取り。‥‥すなわち、タイムシートを打ち込んでタイムリマップに変換して、背景とセルを読み込んで適用して、etc‥‥という作業スタイルに対して、「最後のご奉公」というか、開発における「最後の戦い」を2020年春の期限ですべきかな‥‥と考えております。

 

私が30代の頃に、苦労に苦労を重ねて作ったxtoolsが、時代に取り残され動作しないまま、朽ち果てて終わるよりは、レストアして復活させて、これから作業する作品に役立ててフィナーレを飾ったほうが、私の中でも大きな区切りができます。

 

 

 

とはいうものの。

 

当時、Adobeのスクリプトを覚えながら作ったので、大盛りパスタのごとくのコードなのよネ‥‥。自分ながら、うんざりするほどのスパゲティ。

 

習得しながらのプログラミングは、最初からスッキリハッキリ明快なコードなんて書けんもん。

 

 

 

なので、ずっと放置していた‥‥というのもありますが、レストアすれば確実にコンポジット作業は快適になります。

 

5〜6カットの特殊カットのヘルプなら、ゼロからAfter Effectsで手作業で組んでも良いですが、今後累計で、何十、何百を作業するともなれば、やはり自動処理アシストツールのパワーは絶大です。もうアニメの撮影をメインにすることはないですが、作画からコンポジットまで一式で依頼されることは度々あるので、ツールを復活させて準備しておくのは決して無駄にはならんでしょう。

 

それに、人災もないしネ。コンピュータは、1168と指定すれば必ず1168に設定して動作しますからネ。私はケアレスミスをよくやらかすので(「1186」とか)、コンピュータのアシストはどんなに経験を積もうが頼もしい存在です。数値的なつじつま合わせは、ほとんどコンピュータに任せて、人間は映像表現を追求すれば良いので、作品作りに集中できます。

 

 

 

コードを全部精査して、若気ゆえにわけのわからんことをしている箇所は直して、すっきりと見通しの良いコードにブラッシュアップして、xtoolsのファイナルバージョンを作ろうと思ってます。

 

 



calendar

S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728293031 
<< July 2020 >>

selected entries

categories

archives

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM