おかしな仕様

レベル/ 対象者:中級/ CINEMA 4Dのおかしな仕様に困っている人
対象ソフトウエア、プラグイン:CINEMA 4D R12

CINEMA 4Dを信じない、マニュアルを信じない、ただ自分の考えたことだけを信じる

冨士 俊雄/ gtofuji@gmail.com
章番号 題名 内容、及び関連する章 作成日/注記
1001 Python 初めに、Pythonのマニュアル、長くて読みにくいプログラム、global、見えないバグ、タブとスペース、型変換、ライブラリの登録、801章 2011.3.10
English Top

 

Step 1

初めに

 Pythonは、私がこれまで使ってきたプログラミング言語、たとえば「BASIC」、「FORTRAN」、「HyperTalk」、「C」、「COFFEE」、「JavaScript」等と比べて、間違いなく最悪の言語です。

 それに比べて、同じくCINEMA 4Dの中で使える「COFFEE」は、Cを簡略化したとても使いやすい言語でした。それでは、なぜ使いやすいCOFFEEを捨てて、最悪のPythonを使わなければならないのかというと、それはCOFFEEの開発が止まってしまったからです。

 COFFEEは、Richard Kurzという一人の優秀なプログラマによって作られました。しかし、彼は既にMAXONをやめてしまい、技術的な問題としてMAXONはCOFFEEの開発を続けられなくなったのです。そこでMAXONは、新しい開発環境を簡単に構築するために、Pythonという「出来合い」のプログラミング言語を採用しました。


 Pythonが広く使われるようになったのは、「オープンソースである」ことと、「オブジェクト指向で、モジュールの追加が容易である」ためです。しかしながら、このような利点はそのまま「設計が混乱している」、「モジュールの管理が面倒」という欠点にもなっています。

 本来であれば、PythonをCINEMA 4Dに導入する際に、MAXONは可能な限りCINEMA 4Dに合わせてカスタマイズするべきでした。それは、昔Richard KurzがC言語をベースにCOFFEEを作った時のようにです。しかし、現状のPythonは「ただ動く」というだけで、使いやすさに関しては何も配慮されていません。


 この章では、Pythonがダメな理由について、COFFEEと比較しながら以下のステップで具体的に説明します。

 

 

Step 2

Pythonのマニュアル

 Pythonを使い始めてまず始めに驚くのは「マニュアルがない」ことです。一応「Plugin Cafe」に行くとPythonのマニュアルがありますが、これは「Python用CINEMA 4Dモジュール」のマニュアルにすぎず、これだけでは役に立ちません。

 また、サンプルコードがなく、引数の詳細なども書かれていないので、マニュアルというより「ただの機能リスト」といった感じです。


 したがって、Pythonを使うには「python.org」に行って、Python本体のマニュアルをダウンロードする必要があります。一応「PyJUG」という日本語のサイトもありますが、ここには古いドキュメントしかありません(2.6)。ただし、現在のCINEMA 4DのPythonも2.6なので、今のところは使えます。

 ところが、Python本体のマニュアルは「Language」と「Library」に別れていて、これら全体から調べたい文字や関数を探すのが一苦労です。一応検索機能は用意されているのですが、ヒットする候補が多すぎて、なかなか目的に場所にたどり着けないのです。

 たとえば私は「global」という文字を検索してみましたが、見つからないので、結局Googleで検索してネット上の解説サイトで調べました。

 つまり、公式なマニュアルはほとんど役に立ちません。「Pythonはユーザー活動が活発だ」と言われますが、それはつまり公式のマニュアルがあまりに使えないので、「ユーザー活動に頼るしかなかった」ということなのです。まったく、典型的な「オープンソース」です。


 結論として、Pythonを使うにはまず「マニュアルは無いもの」と覚悟する必要があります。そして、基本機能についてはネット上の解説ページをはしごして調べ、CINEMA 4Dに関する機能についてはCGTalkなどの掲示板で質問するしかない、と私は思います。というか、実際に私はそうしてPythonを勉強しています。

  せめてMAXONには、CINEMA 4Dの関数を含めた全関数のリストを作成し、そこから各マニュアルに飛べるようにしてほしいものです。そもそも初心者には、ある文字が「関数」なのか「文」なのか「変数」なのか「値」なのかさえ判別できません。さらに、関数や文の説明が3種類のマニュアルに分散しているとしたら、自分で調べるのは無理です。こんな状態では「使えなくて当たり前」でしょう。

 また、できればCOFFEEから移行する人間のために、COFFEE関数とPython関数の対応表みたいなものを作ってもらいたいものですが、そのようなものはありません。

 

1. Pythonライブラリマニュアル
The Python Standard Library

2. Python言語マニュアル
The Python Language Reference

3. CINEMA 4D Python SDK
CINEMA 4D R12 Python SDK

 上記の3っつのマニュアルに出てくる用語をまとめてリスト化したテキストファイル

 

 

Step 3

長くて読みにくいプログラム

 次に、実際にPythonのコードをいじってみましょう。

 CINEMA 4Dを起動して新規シーンを開き、ヌルオブジェクトを作成し、「XPresso」タグを作成して下さい。そして、XPresso編集で「新規ノード -> XPresso -> 計算 -> Python」を選択して下さい。

図1001-1

 そして、「Python」ノードを選択して属性マネージャを開き、「Pythonエディタを開く」ボタンを押して下さい。すると「エディタ」ウインドウにPythonのコードが表示されます。

図1001-2

 まず、このデフォルトのコードを見ただけで「なんかおかしい」と感じるはずです。なぜなら、COFFEE のデフォルトコードが「4行」しかないのに対して、Pythonのデフォルトコードは「7行」もあるからです。

図1001-3

 まあ2行目の「#Welcome to the world of Python」はコメント行なんで、すぐに消してしまって構いません。しかし、無駄なコメントを追加する辺りからしてPythonは能天気です。

 

 これに対して、1行目の「import c4d」と6行目の「global」は、消すとPythonが動作しなくなります。それではやってみましょう。

 まず、「Python」ノードを選択し、属性マネージャで「Input1」の値に「1」を、「Input2」の値に「2」を入力します。次に「結果」ノードを作成し、「Python」ノードの「Output1」ポートにつなぎます。最後に、エディタでPythonのデフォルトコードから「1、2、3、4、6行目」を削除してから「コミット」ボタンを押して下さい。

図1001-4

 すると、「コンソール(Python)」ウインドウに次のようなエラーが表示されます。

図1001-5

 ちなみにCOFFEEノードの場合は、カッコをたたんで2行に縮めても問題なく動作します。

図1001-6


 実は、Pythonの1行目の「import c4d」はこのプログラムで使うライブラリへのリンクを、6行目の「global」はグローバル変数の宣言を表していて、これらを削除するとプログラムを実行できないのです。

 もちろんCOFFEEでも、プログラムを実行する際にライブラリへのリンクやグローバル変数の宣言は必要ですが、これらは内部で自動的に処理されるので、ユーザーが意識してプログラムの中に書き込む必要はありません。この点は、「CINEMA 4D専用」に作られたCOFFEEと、「出来合い」のPythonとの大きな違いです。

 Pythonの紹介では、Pythonの利点としてよく「プログラムを読みやすい」という点が上げられます。しかし、他のプログラム言語の2倍も長くなるプログラムを「読みやすい」とは、私には到底言えません。

 

 

Step 4

global

 それでは、Pythonのエディタに戻り、「import」と「global」を戻して「コミット」
して下さい。

図1001-7

 今度は正しく実行できたはずです。

 

 それでは、次に出力ポートと結果ノードを2個に増やしてみます。そして、新しく追加した「Output2」ポートには「Output2 = Input1 * Input2」というプログラムを追加します。したがって、「Output2」につながった「結果」ノードには「2」が出力されるはずです。

図1001-8

 ところが、「コミット」するとエラーが返ってきます。

図1001-9

 これは、新しく作った「Output2」出力ポートが「main」関数内でグローバル変数として宣言されていないからです。そこで、4行目の「global Output1」を「global Output1,Output2」に変更し、再度「コミット」すると今度は正しく実行できたはずです。

図1001-10

 

 なんて面倒な構造なんでしょうか。Pythonノードに出力ポートを追加したら、その都度「global」文の中にその名前を追加しなければならないのです。もし出力ポートを100個追加したら、「global」文の中で宣言する変数の数も100個になります。また、出力ポート名を変えたら、その都度「global」文の中の宣言も変える必要があります。

 「C」でも「COFFEE」でもこんな下等な作業は全部自動的に処理されるのに、Pythonでは全て「手作業」でやらなくてはならないのです。なぜこんな仕様になっているのか本当に疑問です。また、こんな下等な言語を「使いやすい」と言っている人達が、それ以前に「どんなヒドい言語」を使っていたのか是非知りたいものです。

 

 

Step 5

見えないバグ

 Pythonでは「見えないバグ」が簡単に発生します。たとえば下の図1001-11左のプログラムは正しく実行できますが、右のプログラムはエラーになります。

図1001-11

 そして、この二つのプログラムに「見た目の違い」は全くありません。だから「見えないバグ」なのです。

 この見えないバグを見つけるには、それぞれのプログラムをコピーしてテキストエディタにペーストし、「不可視文字」を表示させる必要があります。

図1001-11

 図1001-11左が正しいプログラム、右がエラーを出すプログラムです。エラーの原因となったバグは最後に追加された「 (スペース)」です。

 

 

 

 

 

Step 5

オブジェクトを作る、NURBS

 最後に、COFFEEノードでポートと情報をやり取りする方法を説明しましょう。まずCOFFEEノードの左上をクリックし、文字ポートを作ります。次にポート名を右クリックし、プルダウンメニューから「名前を変更」を選択し、判りやすい名前に変更します。ここでは「n_in」としておきましょう。

 次に、このポートを定数ノードにつなぎます。これで、COFFEEノードは定数ノードから「Hello World!」という文字情報を受け取れるようになりました。

図801-16

  次に、エクスプレッションエディタに戻り、プログラムを次のように変更し、実行ボタンを押します。すると、コンソールにもう一行「Hello World!」が増えたはずです。簡単ですね。

println(n_in);

図801-17

  次に、COFFEEノードの右側にも文字ポートを追加し、名前を「n_out」とします。そしてプログラムに次の1行を追加します。

n_out= n_in;

 そして、このn_outポートを結果ノードにつなぎます。

図801-18

 すると結果ノードには前と同じように「Hello World!」が表示されたはずです。表示は「Hello World!」のまま変りませんが、この文字データはCOFFEEノードの中を通ってきたものです。ですからCOFFEEノードの中でプログラムを追加すれば自由に操作できます。

 たとえばプログラムを次のように変更すれば、結果ノードの表示は「Hello World + COFFEE」に変化したはずです。ここで「stradd()」は文字を追加する関数です。

n_out= stradd(n_in, " + COFFEE");

図801-19

 また、プログラムを次のように変更すれば、結果ノードの表示は「12」に変ります。12は「Hello World!」の文字数で、「sizeof()」は文字数を調べる関数、「tostring()」は整数データを文字データに変換する関数です。

n_out= tostring(sizeof(n_in));

図801-20

 たくさんあるCOFFEEの関数を憶えるのは大変だと思うでしょうが、憶える必要は全くありません。その度にマニュアルを調べればいいのです。私もマニュアルを調べながらこのテキストを書いていますが、世の中そんなもんです。また、マニュアルを読んでも判らないことはどんどん掲示板に質問しましょう。

 COFFEEのマニュアルは以下のページから入手できます。

http://www.maxon.net/en/support/plugin-cafe.html

 

 

Step 6

アニメーションを作る

 最後に、COFFEEノードでポートと情報をやり取りする方法を説明しましょう。まずCOFFEEノードの左上をクリックし、文字ポートを作ります。次にポート名を右クリックし、プルダウンメニューから「名前を変更」を選択し、判りやすい名前に変更します。ここでは「n_in」としておきましょう。

 次に、このポートを定数ノードにつなぎます。これで、COFFEEノードは定数ノードから「Hello World!」という文字情報を受け取れるようになりました。

図801-16

  次に、エクスプレッションエディタに戻り、プログラムを次のように変更し、実行ボタンを押します。すると、コンソールにもう一行「Hello World!」が増えたはずです。簡単ですね。

println(n_in);

図801-17

  次に、COFFEEノードの右側にも文字ポートを追加し、名前を「n_out」とします。そしてプログラムに次の1行を追加します。

n_out= n_in;

 そして、このn_outポートを結果ノードにつなぎます。

図801-18

 すると結果ノードには前と同じように「Hello World!」が表示されたはずです。表示は「Hello World!」のまま変りませんが、この文字データはCOFFEEノードの中を通ってきたものです。ですからCOFFEEノードの中でプログラムを追加すれば自由に操作できます。

 たとえばプログラムを次のように変更すれば、結果ノードの表示は「Hello World + COFFEE」に変化したはずです。ここで「stradd()」は文字を追加する関数です。

n_out= stradd(n_in, " + COFFEE");

図801-19

 また、プログラムを次のように変更すれば、結果ノードの表示は「12」に変ります。12は「Hello World!」の文字数で、「sizeof()」は文字数を調べる関数、「tostring()」は整数データを文字データに変換する関数です。

n_out= tostring(sizeof(n_in));

図801-20

 たくさんあるCOFFEEの関数を憶えるのは大変だと思うでしょうが、憶える必要は全くありません。その度にマニュアルを調べればいいのです。私もマニュアルを調べながらこのテキストを書いていますが、世の中そんなもんです。また、マニュアルを読んでも判らないことはどんどん掲示板に質問しましょう。

 COFFEEのマニュアルは以下のページから入手できます。

http://www.maxon.net/en/support/plugin-cafe.html

 

 

Step 7

レンダリングする

 最後に、COFFEEノードでポートと情報をやり取りする方法を説明しましょう。まずCOFFEEノードの左上をクリックし、文字ポートを作ります。次にポート名を右クリックし、プルダウンメニューから「名前を変更」を選択し、判りやすい名前に変更します。ここでは「n_in」としておきましょう。

 次に、このポートを定数ノードにつなぎます。これで、COFFEEノードは定数ノードから「Hello World!」という文字情報を受け取れるようになりました。

図801-16

  次に、エクスプレッションエディタに戻り、プログラムを次のように変更し、実行ボタンを押します。すると、コンソールにもう一行「Hello World!」が増えたはずです。簡単ですね。

println(n_in);

図801-17

  次に、COFFEEノードの右側にも文字ポートを追加し、名前を「n_out」とします。そしてプログラムに次の1行を追加します。

n_out= n_in;

 そして、このn_outポートを結果ノードにつなぎます。

図801-18

 すると結果ノードには前と同じように「Hello World!」が表示されたはずです。表示は「Hello World!」のまま変りませんが、この文字データはCOFFEEノードの中を通ってきたものです。ですからCOFFEEノードの中でプログラムを追加すれば自由に操作できます。

 たとえばプログラムを次のように変更すれば、結果ノードの表示は「Hello World + COFFEE」に変化したはずです。ここで「stradd()」は文字を追加する関数です。

n_out= stradd(n_in, " + COFFEE");

図801-19

 また、プログラムを次のように変更すれば、結果ノードの表示は「12」に変ります。12は「Hello World!」の文字数で、「sizeof()」は文字数を調べる関数、「tostring()」は整数データを文字データに変換する関数です。

n_out= tostring(sizeof(n_in));

図801-20

 たくさんあるCOFFEEの関数を憶えるのは大変だと思うでしょうが、憶える必要は全くありません。その度にマニュアルを調べればいいのです。私もマニュアルを調べながらこのテキストを書いていますが、世の中そんなもんです。また、マニュアルを読んでも判らないことはどんどん掲示板に質問しましょう。

 COFFEEのマニュアルは以下のページから入手できます。

http://www.maxon.net/en/support/plugin-cafe.html