« このブログも、そろそろ10万アクセスですかぁ… | トップページ | C4D Python R12 テスト:ポイントオブジェクトのポイントを選択してみる。 »

C4D Python R12 テスト:ポイントオブジェクトの選択ポイントを表示する。

C4D Python 放ったらかし…
C4D Python SDKがR12で大幅に改編されたので、C4D R11 Python コードをR12で使うには、コードを全面的に書き換えなければ使えないんだね…

今回の記事はC4D R12 Demoを使用しているので、R12未満の方はごめんなさい。

C.O.F.F.E.E.と比較しながら…
できるだけ、2つとも同じようになるようにしたので、ベストなコードとは言えませんよ…

スクリプトマネージャではなく、オブジェクトに取り付けたPythonタグとC.O.F.F.E.E.タグとの比較です。

Getselectpoints_01

ポイントオブジェクト(ポリゴンオブジェクト、またはスプラインオブジェクト)のポイントを選択します。

Getselectpoints_02

イベントが起こると、それぞれのコンソールに選択されたポイントが同じように表示されます。

Python C.O.F.F.E.E.
"""
ポイントオブジェクトの選択ポイントをコンソールに表示する
2011.1.18
"""


import c4d


def SelectPoints(obj):
    if not isinstance(obj, c4d.PointObject):
        return None
    sel_pts = obj.GetPointS()
    res_pts = []
    for c1 in xrange(obj.GetPointCount()):
        if sel_pts.IsSelected(c1):
            res_pts.append([c1, obj.GetPoint(c1)])
    return res_pts














def main():
    objs = op.GetObject()
    res = SelectPoints(objs)
    if not res:
        return

    print objs.GetName()

    for c in xrange(len(res)):
        print res[c][0], res[c][1]
/*
ポイントオブジェクトの選択ポイントをコンソールに表示する
2011.1.18
*/





SelectPoints(obj)
{
  if(!instanceof(obj, PointObject))return null;
  var sel_pts = obj->GetPointSelection();
  var res_pts = new(array, sel_pts->GetCount());
  var c1, c2;
  for(c1 = 0, c2 = 0; c1 < obj->GetPointCount(); c1++)
  {
    if(sel_pts->IsSelected(c1))
    {
      var pt = new(array, 2);
      pt[0] = c1;
      pt[1] = obj->GetPoint(c1);
      res_pts[c2] = pt;
      c2++;
    }
  }
  return res_pts;
}



main(doc,op)
{
  var res = SelectPoints(op);
  if(!res)return;

  println(op->GetName());

  var c;
  for(c = 0; c < sizeof(res); c++)
  {
    println(res[c][0],res[c][1]);
  }
}
コンソール(Python) コンソール
球体
22 Vector(80,902, 50, -30.902)
23 Vector(68.172, 71.657, -14.762)
29 Vector(68.172, 71.657, 14.762)
30 Vector(95.542, 0, -29.524)
106 Vector(68.819, 42.533, -58.779)
108 Vector(85.065, 52.573, 0)
110 Vector(95.106, 26.287, -16.246)
111 Vector(58.779, 68.819, 42.533)
球体
22[80,901703,50.000000,-30.901699]
23[68.171837,71.656693,-14.762091]
29[68.171837,71.656693,14.762091]
30[95.542259,0.000000,-29.524181]
106[68.819099,42.532539,-58.778526]
108[85.065079,52.573112,0.000000]
110[95.105652,26.286556,-16.245985]
111[58.778526,68.819099,42.532539]

変数

Python C.O.F.F.E.E.
sel_pts c4d.BaseSelect BaseSelect
res_pts list array
c1 int int
c2 --- int
pt --- array
op c4d.BaseTag BaseObject
objs c4d.BaseObject ---
c int int
res list array

Python及び、C4D Python SDKを学習しながらなので、トンチンカンな思考錯誤状態です。
暖かい目で見守ってください…

このスクリプトは、main()関数とSelectPoint()関数で構成しました。

main()関数では、スクリプトが取り付けられたオブジェクトを取得し、SelectPoint()関数へ渡します。
返ってきたポイント配列をコンソールに表示します。

SelectPoints関数はC4Dのオブジェクトを渡たすと、ポイントオブジェクト(ポリゴンオブジェクト/スプラインオブジェクト)であれば選択されたポイントリスト(配列)を返します。

C.O.F.F.E.E.よりPythonの方が変数などの宣言が無い分、短くなりました。

このスクリプトは、具体的な説明をしなくても短いので読んでくれたら分かると思うんだけど…

コメント文は…

'''コメント'''
"""コメント"""

複数行の場合は、シングルクォートかダブルクォートの三連で囲むようだ。
C.O.F.F.E.E.だと、/*~*/だね。

1行の場合は…

#コメント

C.O.F.F.E.E.の場合は、/~

Pythonの場合は、各機能がモジュールで扱われているようで、スクリプトで必要なモジュールを読み込んで使うらしい。

import モジュール名

C.O.F.F.E.E.では、include ファイル名 かな。
C4D Python SDKは幾つかのモジュールに分けられているけど、C.O.F.F.E.E.SDKは分けられていないので、小さなスクリプトだと使うことはまず無いかと…

C4D Python SDKのモジュール
モジュールとは言っても、TPとかMoGraphとかMoccaとか言うことではないよ。

c4d オブジェクトやタグ、トラックなど
c4d.bitmaps 画像
c4d.documents シーンファイル?
c4d.gui ダイアログなど?
c4d.plugins 各種プラグイン?
c4d.strage ファイル関連?
c4d.utils その他の様々な機能?

まだC4D Pthon SDK を少ししか把握していないので、具体的には理解していないのだ…

今回は、ポイントオブジェクトの選択されたポイントを取得するだけなので、c4dモジュールだけでよいのだ。

import c4d

関数の記述は

def 関数名(引数 [, 引数[, 引数[, ...]]]):

こんな感じだ。
C.O.F.F.E.E.の場合は、関数名(引数 [, 引数[, 引数[, ...]]]){...}で…
Pythonの場合は、def を頭に付け…ブロックの開始であるコロンを付ける。
関数内は、もちろんインデントする…
コロンは、if for while等でも使うけど、自分はよく忘れるんだ…

main()関数

以前にも書いたと思いますが、C4D Pthonタグでは、docとopはグローバルで、docは、現在のシーンファイルでopはPythonタグ。C.O.F.F.E.E.の場合のopは、C.O.F.F.E.E.タグが取り付けられているオブジェクトで、docとopはローカルでした。

c4d.BaseTagのGetObject()メソッドを使い、opを取り付けているオブジェクトを取得します。

SelectPoint()関数へオブジェクトを渡し、返ってきたリストをforループを使ってコンソールに表示します。

forで使用しているxrange()は、Pythonの組み込み関数で範囲を示すもの。以前書いた記事で使用したリストを生成するrange()とは違ます。

範囲
xrange(a) 0 ~ a-1
xrange(a, b) a ~ b-1

3DCGの場合、1000や2000のポリゴンやポイントを繰り返し処理をする事はめずらしく無いだろう。そために、インデックスをリストとして生成するrange()を使うとメモリを無駄に使うと言うことだ。この様な場合はxrange()を使用しよう。

リストのインデックス数を取得するには、組み込み関数のlen()を使用しました。
C.O.F.F.E.E.では、sizeof()です。

オブジェクトの名前の取得は、c4d.BaseList2DのGetName()メソッドです。

SelectPoint()関数は…

渡されたオブジェクトがポイントオブジェクトでは無い場合、処理ができませんのでポイントオブジェクトか否かを判定します。

Pythonの組み込み関数のisinstance()を使います。
C.O.F.F.E.E.の場合はinstanceof()です。

ポイントの選択状況を格納しているc4d.BaseSelectを取得します。
c4d.PointObjectのGetPointS()メソッドを使用します。
C.O.F.F.E.E.の場合は、PointObjectのGetPointSelection()です。

選択ポイントのポイント番号と座標を格納するリストを用意します。

C.O.F.F.E.E.の配列の宣言と割り当ては…
new(array , インデックス数[ , インデックス数[ , インデックス数[ , ... ]]])を使って先にインデックス数を指定して割り当てます。
Pythonには、インデックス数を指定して割り当てる方法は、無いのかなぁ…よく分からない…

リスト名 = []

これで空のリストを作成する。
リストのappend()メソッドを使いリストの末尾に要素(ポイント番号と座標)を次々追加する事にしました。

先ほど取得したポイントの選択状況であるc4d.BaseSelectのIsSelected()メソッドにポイント番号を渡して、そのポイントが選択されているか否かで判別します。
選択されていれば、リストにポイント番号と座標を追加します。
C.O.F.F.E.E.の場合も、BaseSelectのIsSelected()で選択されているかを判別します。

Pythonには、多次元のリストが無いようだったので(学習中なので、まだ詳しく分かりません)、リストの中にリストを格納しました。
C.O.F.F.E.E.も同じように、配列の中に配列[[int] num, [vector] point]を格納しました。

最後に作成したリストをreturnで返します。

今回はこの辺で…
間違っていたらごめんなさい…

学習中なので、あまり参考にはならないと思いますが…
小さな事をコツコツ積み重ねて行こうかと…

|

« このブログも、そろそろ10万アクセスですかぁ… | トップページ | C4D Python R12 テスト:ポイントオブジェクトのポイントを選択してみる。 »

コメント

コメントを書く



(ウェブ上には掲載しません)




« このブログも、そろそろ10万アクセスですかぁ… | トップページ | C4D Python R12 テスト:ポイントオブジェクトのポイントを選択してみる。 »