抽象化スキル(プログラミング論ではない)

めも。

http://blogos.com/article/46933/
http://ameblo.jp/takuroo3799/entry-11594898735.html
https://books.google.co.jp/books?id=Rkcx7wmjgDwC&pg=PA119&lpg=PA119&dq=%E6%8A%BD%E8%B1%A1%E5%8C%96+%E3%82%B9%E3%82%AD%E3%83%AB&source=bl&ots=FqdqYFK8Kq&sig=GdS8cuadqPCSFeH1Y3dx8MgXuIA&hl=ja&sa=X&ei=-SlSVa30D6a0mwXYo4CgDA&ved=0CD0Q6AEwBjgK#v=onepage&q=%E6%8A%BD%E8%B1%A1%E5%8C%96%20%E3%82%B9%E3%82%AD%E3%83%AB&f=false
http://kajikenblog.com/?p=717

これはプログラミング論だけど、具体例としてメモっておく。。
http://masuda220.jugem.jp/?eid=381

CS6のネットワークレンダリング用の設定について

CS6で、ちょっと不思議な設定が必要になっているのでメモ。

>監視フォルダーとレンダリングエンジンを使用したネットワークレンダリング
http://helpx.adobe.com/jp/after-effects/using/automated-rendering-network-rendering.html#WS3878526689cb91655866c1103a4f2dff7-79a2a
———————————————————–
 非ロイヤリティベアリングモードを有効にするには、ae_render_only_node.txt という名前の空のファイルをユーザーのアカウントの種類に応じて次のいずれかの場所に配置します。

 1.After Effects をレンダリング専用マシンにインストールします。
 2.ae_render_only_node.txt という名前の空のファイルをユーザーのアカウントの種類に応じて次のいずれかの場所に配置します。

 •Mac での場所:
 /Users//Documents/
 /Users/Shared/Adobe/

 •Windows での場所:
 C:\Users\\Documents
 C:\Users\Public\Documents\Adobe

 あと、aerender.exeのオプション設定は以下のような内容。
 試してみると、最低限 -project 又は -comp を指定しないとレンダリングしてくれないっぽい。
 また -log を使えばファイルにログを残しておくことが出来るので、標準出力から取ろうと頑張る必要とか特にない。

>aerender によるレンダリングの自動化
http://helpx.adobe.com/jp/after-effects/using/automated-rendering-network-rendering.html#WS8A8CD670-4A72-4fb5-AE8E-CB9E232EC0B5a

カオス理論 という概念

プログラミングというより、数学の話だけど…発端はコンピュータ・シミュレーション技術の発展が生んだ概念なので、メモ。

シミュレーション計算をやると必ず陥る問題で、
初期値の極小値の変更が、結果にとてつもなく大きな違いを生む場合が存在する。
というのがあります。

これは基本的に、パラメータや計算方法が大雑把な為に起こる。というように、数学者の間では考えられていたそうです。
でも、実際はそうでもない。
ということが、コンピュータ・シミュレーションの研究から明らかになって、今に至る…と。

http://www.prings.com/opendoor/chaos1.htm

理論としては、『どのあたりまでは判る、どの辺から判らなくなる』みたいなことを判別しよう、というものらしい。

古いアプリ実行時に『お使いの PC にあるアプリには、Windows の次の機能が必要です。 NTVDM』と出たら

>[Windows 8.1]16ビットアプリケーションを動かす

[Windows 8.1]16ビットアプリケーションを動かす。

古い古いアプリケーションだと、現行の64bitアプリではなく、32bitでもなく、最初期のWindowsの使う16bitのアプリというものがあって、これを動かすのに必要になるモジュール。
デフォルトではインストールされていないので、必要に応じて一回入れてあげる必要がある。

つか、むしろMS-DOS Playerをお勧めしたいです。

レンダレイヤのコマンドについて

以下、操作用の関連コマンドを列挙。

・createRenderLayer
 新しいレンダー レイヤを作成します。
 ※レンダレイヤに含まれるのは、DAGノード。

・editRenderLayerAdjustment
 このコマンドを使用して、レンダー レイヤの調整を作成、編集、照会します。
 調整を行うことで、アクティブなレンダーレイヤに応じ、異なるアトリビュート値やコネクションを使用できるようになります。

・editRenderLayerGlobals
 すべてのレンダー レイヤに共通するパラメータ値を編集します。
 baseId や mergeType などのパラメータはプリファレンスとして格納され、currentRenderLayer などのパラメータはファイルとして格納されます。

・editRenderLayerMembers
 このコマンドを使用して、レンダー レイヤのメンバーシップを照会または編集します。
 メンバーになれるのは、トランスフォームノードおよびジオメトリ ノードに限られます。
 レンダー時には、レンダー レイヤのメンバーのすべての子孫もレンダー レイヤに含められます。

・frameBufferName
 指定した renderPass の renderLayer とカメラの組み合わせに対するフレームバッファ名を返します。
 また、このコマンドではオプションで、frameBuffer 名が目的のファイルフォーマットによって指定された最大長に従うように、名前切り捨てアルゴリズムを適用できます。

・renderPassRegistry
 レンダー パスと関連する照会情報。
 ※renderSettingsに登録した情報を取得するコマンド。

・setRenderPassType
 このコマンドでは renderPass ノードの passID を設定し、対応するレンダー パス定義によって指定されたカスタムアトリビュートを作成します。
 ※ユーザーカスタムなrenderPass編集用コマンド。

anim Export

 anim形式でアニメーションを吐き出す機能なんだけど、元々はfbxとのやり取り辺りで付いた機能(らしい.. 正しいかどうかは各自調べて下さい)。
 差し先が完全に決まってしまうので使い方が限定されるけれど、何もない時の手段として覚えておこう。

プログラムの信頼性を高める”テスト” という概念と手法

 最近の開発言語が Pythonメインだけど、そのあたりを基準に書けない..orz

 参考サイト: ソフトウェアテスト@wiki
 http://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%86%E3%82%B9%E3%83%88

 テストの基本は、カバレッジ(網羅率)を基準にして、プログラムの実行経路を網羅するようにテストコードを作成する。
 参考サイトのホワイトボックステストの項目にある通りといえる。

 上記コードの場合、すべての行を実行(命令網羅(C0))するには -1を与えるのが適当。
 『1 == abs(-1) 』がテストコードとして実行できれば、C0テストはクリアとなる。
 同じように『1 == abs(-1) 』と『0 == abs(0)』を実行できれば、C1テストはクリアとなる。
 上記の場合には複数の条件がないので、C2テストはそもそも必要ないが、複数の条件がある場合にはそれら全てを実行できたらクリアとなる。

 ホワイトボックステストは、テストのごく基本になる手法だが、実際の開発では全テスト網羅するということ自体が非現実的になる場合の方が多いので、この方法は一般的に上記のように小さな関数やモジュールレベルの開発で用いられる方法。

 同じ基本のテストに、参考で次に書かれているブラックボックステストが挙げられる。
 こちらのテストは、プログラムの中の動作がどのように出来上がっているか知らない体で、『入力に対して求める結果』を元にテストする方法。

 上記関数の場合は実装上はあまり問題になりそうな部分がない。テストとしては、1, 0, -1を与えれば基本的にはクリアと言える。その上で値の範囲として 128,129,-127,-128 とか 32768,32769,-32767,-32768のように 8/16ビット符号付きの範囲境界でのテストを行うなど、関数に入力するであろう値の範囲で問題になりそうな境界部分をテストするなどを行う場合が考えられる。

 wikiにもあるように、実際に想定されるものはもう少し複雑な話。
 例えば24時間制で時刻が入力される関数があるとして、『1日9時間までは通常料金。9時間を越えると超えた分は1.25。休日は基本1.35に割り増し。』というような処理をテストする場合が例としては判りやすい。
 こういった場合には、デシジョンテーブルと呼ばれるパターン表を作成して、それぞれのパターンがどのような結果になることが望まれるのかを記述したものを用意した上で、テストケースのコードを作成する。

9h未満 9h超え
平日 x1.00 x1.25
休日 x1.35 x1.60

 単体/結合テストは、文字通り開発しているコードを関数レベルでテスト、次にライブラリのような括りで結合テストを行った上で、製品から利用する結合テストという流れ。
 ライブラリが製品の場合は、関数をまとめたライブラリのレベルの結合テストの時点で終わり。

 スタブ(stub)というのは、テスト用に作られる仮想部品のこと。
 例えば、テストする関数がなにか別のモジュールを呼び出し、戻ってきたデータを用いて処理を行わないといけない場合に、呼び出しモジュールの代わりにデータを返してくれるコードを作成して、これを本来呼び出すモジュールの変わりにする。この身代わりモジュールのことをスタブと呼ぶ。

 テストドライバというのは、テスト用の呼び出し実装のこと。
 スタブの逆に、テストしたいモジュールを呼び出す実装。本来のモジュールの変わりに用いられる仮想の親モジュール。
 普通小さいモジュールを作っている場合はこのテストドライバとして、テスト用のフレームワークを利用することになる。

 最終的な製品レベルのモジュールになると、UIとかの絡みがあるので、テスト用フレームワークだけでは足りない場合もあるが、こういった場合にはQAチームを動員して(マウス自動操作ツールも使用しつつ)実際のUIでの操作テストを実施することになる。

 そして、テスト駆動開発(Test Driven Development)
 これは、開発時に本来開発する対象のコードを書く前に、そのコードをテストするコードを作成しておいて、そのテストをクリアするコードを書く。コードを書いていて気づいたテスト要件は随時テストに追加。というような流れで、コーディングを進める開発方法。

 基本的なサイクルは、下記の通り。
 ・失敗するテストを書く
 ・できる限り早く、テストがパスするような最小限のコード本体を書く
 ・コードの重複を除去する

 参考サイト:
 http://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA

 …で、この手法の本来のメリットは1回コードを書いただけでは判らない部分にもある。
 当初動いていたコードが突然動かなくなる、ということも起こる。つまり、日々同じコードを更新していくような作業をしている場合には、実装が複雑になるせいで仕様にない振る舞いを起こすようになったり、知らないうちに当初の設計では想定していないような振る舞いが起こる、そんな場合も発生する。
 TDDでは、deploy時に常にテストドライバを使った新しいコードの信頼性確認を実施する。新しいコードが、今までと変わりなく振舞えば良し。振舞わない場合にはアラートが上がる。
 これらは、『まずテストありき(Test, first.)という考えによって、より信頼性の高いコード生産は実現される』という思想に基づいている。

 最近では、この開発者主導の考えから少し視点を変えて行おうという発想で、ビヘイビア駆動開発(Behavior Driven Development)という手法が提唱されている。
 テストの記述方法自体は、基本的に同じもの。
 それは単にTDDの語彙『test/assert』をBDDの語彙『should/Verify』に置き換えているだけ。と言われるくらいの違いだとか。
 コードが正しいかどうかテストする…というものではなく、コードの仕様を記述しそれはそのままテストになる…というのがBDDの基本的な思想。

 Python向けのBDDツールとしては、pyspecというツールが存在する。

 参考サイト:
 http://pyspec.codeplex.com/

Pythonのテスト環境

>>pytest
参考サイト:
 http://pytest.org/latest-ja/getting-started.html

 予めeasy_installを入れておく。
 その上で、上記サイトを参考にインストールを行えばOK。

 基本的には、コマンドラインから “py.test”と入力するだけ。
 カレントディレクトリのテストコード記述(接頭子:”test_” の関数)を勝手に見つけて、実行してくれる。

 より実践的なテスト方法については、別途調査が必要..
 参考は ⇒http://pytest.org/latest-ja/goodpractises.html#goodpractises

>>nose
参考サイト:
 http://aohta.github.io/nose_tutorial/tips/install.html
 http://d.hatena.ne.jp/Ponsuke/20090712/1247391982

 例によって、easy_installでインストールできる。
>easy_install nose

 noseにはプラグインがあって、カバレッジやテスト件数を記録してくれるものがあるそうで、以下の2つを入れる模様..
>easy_install coverage
>easy_install unittest-xml-reporting

PySideでの モディファイアキーの状態取得

参考ページ:
http://stackoverflow.com/questions/8772595/how-to-check-if-a-key-modifier-is-pressed-shift-ctrl-alt

正規表現で、ファイル名からフレーム数を抜き出すには

とりあえず 『(ドライブ名) (フォルダパス) (ファイル名)』とあって、
ファイル名内が『ベース名.フレーム番号.拡張子』のようになっている場合の、フレーム数の取得。

参考サイト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions

視線と垂直に交わる平面上の1点を求めるには(補足)


そもそもはdevkitのmoveTool.pyが perspカメラに対応していなくて、

どうやったら『パースペクティブビュー上でドラッグした点の行き先』を計算できるのか..

という疑問から始まった。

話としては、『平面の方程式』を手掛りにして『平面と直線の交点を求める』ということになるのだが、
いろいろ考えてはみたものの、カメラの正面方向のベクトルに直行する平面上の1点がどうなれば求まるのか、というところに数学できない君の自分は結局辿りつくことが出来なかった。

そもそも、平面の方程式を自分は知らなかった..
平面の方程式というのは、平面上の2点p,qと平面の法線ベクトルの値が揃えば、以下の式は成り立つ、という公式。

点q(x,y,z)を通り,\( \vec{N}=(a,b,c) \) を法線ベクトルとする平面αの方程式

\( ax+by+cx+d=0 \)

高校数学で内積・外積あたりを勉強していると、以下のような形で証明される。

平面α上の点q(x,y,z)に対して \( \vec{N} \perp \vec{P} \) から ( \( \vec{P} \) は平面上の点pから点qへ向かうベクトル )
 

\( \vec{N} \cdot \vec{P}=0 \)
\( (a,b,c) \cdot (x-P_x,y-P_y,z-P_z)=0 \)
\( a(x-P_x)+b(y-P_y)+c(z-P_z)=0 \)

 
以上により、
\( ax+by+cz+d=0 \) が求まる
(ただし \( d=-aP_x-bP_y-cP_z \) は、定数とする)

今回自分がやりたかったのは、『パースペクティブ視点で選択頂点をドラッグした時の移動先を求める』という処理。

 •平面と直線の交点を求めるには平面と直線がわかっていないといけない。
 •直線は、視点の位置と3d上のマウスポインタの方向(M3dViewから得たもの)で指定される。
 •平面は、空間上の一点と法線ベクトルで指定される。
 •平面を指定するための空間上の一点がpで、今回はこれが移動前の位置。

視点・視線ベクトル・点p(選択頂点の元の位置)までは判っているので、あとはOpenMayaのM3dViewクラスの機能と上の式があれば目的は達成できる。

ということで、実際にやってみるとまだもう1つ問題が残っていて、起点となる位置(点p)を確定できていなかった..orz
※moveTool.pyの場合、平行投影表示の視点の場合を想定した実装の為、M3dView.viewToWorld関数で取得するワールド座標がpersp視点の場合には求める座標になっていなかった。

問題を解消する方法はこれまたいろいろとあるハズだが、思い付いたのは選択頂点のある1頂点の座標(もしくは選択頂点の中心座標)を取得して、一旦M3dView.worldToView関数でコンテキスト面に投影する方法。

moveTool.pyの実装自体がコンテキスト面⇒ワールド空間への座標変換と、ワールド空間での始点と終点の相対的な移動量計算なので、始点の基準になる1点をコンテキスト面に投影出来てしまえば、その座標とマウス位置(実際の始点や終点)との2D的なオフセットを得ることが出来る。(既に分かっている始点、視線ベクトルに加え、足りなかった点pとして『始点の基準になる1点と、2D的なオフセット』が手に入ったことになる。)

ドラッグ中は、コンテキスト座標基準でオフセットを加えた2D位置を元に先の説明の交点計算を行うことで、最終的な移動先(ワールド空間上の1点)を得られる。
何故ならば『視線と垂直に交わる平面』とコンテキスト面は、どちらも視線と垂直に交わる面であり互いに平行な面。
したがって、コンテキスト座標基準でオフセットを加えた2D位置というのは、そのまま『視線と垂直に交わる平面上に”平行投影された”1点』となるからである。

視線と垂直に交わる平面上の1点を求めるには

そもそもはdevkitのmoveTool.pyが perspカメラに対応していなくて、
どうやってパースペクティブビュー上でドラッグした点の位置を計算できるのか..という疑問から出てきた話題。

添付画像は、教えてもらった求め方。(平面の式から、点qを求めるところまでの一連の導出)
視線に垂直に交わる平面上の1点を求める(1)

視線に垂直に交わる平面上の1点を求める(2)

視線に垂直に交わる平面上の1点を求める(3)

平面の方程式の解法..は、このへんを参考にすれば、判るかも。
http://21.xmbs.jp/shindou-11684-n3.php?guid=on&page=5&view=1

componentScaleManip.cpp を ~.pyに書き換えてみた

 どういうわけかdevkit内のサンプルに vertex編集関連のマニピュレータ pluginのPython版が見当たらなかった(入っているmoveManip.pyは、コンポーネントの編集に非対応だった)ので、試しにC++のコード(componentScaleManip.cpp)をPythonに書き換えてみた。
 元のコードは サーフェースのCV編集をする実装なので、meshのvertex, pnts基準で編集するように書き換え。
 エラーチェック処理の端々まで動作確認していないので、変なところはDo It Your self で。
続きを読む componentScaleManip.cpp を ~.pyに書き換えてみた

近傍頂点の検索

>get closest vertex in maya using python(@djx blog)
http://www.djx.com.au/blog/2013/07/07/get-closest-vertex-in-maya-using-python/

 手続き的な部分が判りづらかったり、pymel使わない人だったりしたので、書き換えてみたが。

 しかし、かえって判りづらいという結果に..

MStatusの扱いについて

完全に忘れてたのでメモ。

>”例外と MStatus” の項を参照 (@Maya 2013 Help, API ガイド > Maya Python API > Maya Python API 1.0 > Maya Python API を使用する)
http://docs.autodesk.com/MAYAUL/2013/JPN/Maya-API-Documentation/index.html?url=files/Maya_Python_API_Using_the_Maya_Python_API.htm,topicNumber=d30e13074

Pythonでは MStatusを用いない, 代わりに、いくつかのルール付けがある。

C++ API メソッドが MStatus 値を返す方法には、2 通りの方法があります。

メソッドの戻り値として返す方法

パラメータ リストの MStatus 変数(通常、最後のパラメータ)へのオプション ポインタとして返す方法

メソッドが関数値として MStatus を返す場合
 メソッドが関数値として MStatus を返す場合、この戻り値は Python で次のように処理されます。

  ・ステータスが MS::kUnknownParameter である場合、文字列 unknown が Python に返されます。
  ・ステータスが MS::kSuccess である場合、何も返されず、例外も発生しません。
  ・それ以外のステータスの場合、何も返されませんが、RuntimeError 例外が発生します。

 MS::kUnknownParameter を特別に処理するのは、MPxNode::compute() に対応するためです。
 API 固有の特別な例外はありません。Maya は単に Python の標準 RuntimeError を使用し、エラー文字列を引数として渡します。

メソッドがポインタ変数を通じて MStatus を返す場合
 API メソッドがパラメータ リストのポインタ変数を通じて MStatus を返す場合、この MStatus は次のように処理されます。

  ・ステータスが MS::kSuccess である場合、例外は発生しません。
  ・それ以外のステータスの場合、何も返されませんが、RuntimeError 例外が発生します。

 つまり、C++ 言語でプラグインを記述する場合に、コードを呼び出しているのが C++ であるか Python であるかに関係なく、これまでどおり MStatus コードを返すことができます。Maya は必要に応じて、これらのコードを Python 例外に変換します。

 Python でプラグインを記述する場合は、MStatus 値を返すのではなく例外を発生させる必要があります。ただし、compute() メソッドでプラグを処理しないことを指示する場合を除きます。この場合、このメソッドは maya.OpenMaya.kUnknownParameter を返します。