« C4D ThinkingParticlesをホンの少しだけ再確認…TPGeneratorとPPass | トップページ | C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-2 »

C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-1

直ぐにでも、パーティクルを生成して見たいけど…
いつもの様に、ダラダラでグダグダな流れになると…

C4D Pythonでは、ThinkingParticlesを扱うには…

c4d.modules.thinkingparticlesの…

TP_MasterSystem
TP_PGroup

この2つのクラスだね…

まずは、C4D Pythonでパーティクルグループを…

パーティクルグループを前回と同じく適当に3個作って…

Python_tp_33

PStormを3個追加して…

Python_tp_07

3個のPStorm #.1~#.3の設定は次のように…
グループ.1~.3までの各グループのパーティクル数が同じにならないようにショット数を設定… カウントでもレートでもどれでも良いのだ…

PStorm #.1
Python_tp_08

PStorm #.2
Python_tp_09

PStorm #.3
Python_tp_10

アニメーションを再生して適当なところで停止させます。

Python_tp_35

各グループのパーティクル数をThinkingParticle設定ダイアログで確認…

Python_tp_36

グループ.1が19、グループ.2が38、グループ.3が57…

これで、準備は整いました。
パーティクルグループから取得できるものは…

  • 名前 (変更可)
  • ビュータイプ (変更可)
  • カラー (変更可)
  • オブジェクトを表示 (変更可)
  • パーティクル数

最上位のパーティクルグループを取得してみよう。
名前をコンソールに表示してみます。

ThinkingParticlesがインストールされていれば、グローバル変数「tp」に格納されています。
これは、TP_MasterSystemです。

試しに、次のコードをスクリプトマネージャ(Python)へ…

Python
'''
最上位のパーティクルグループを取得
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()
    print root_gp.GetTitle()
   

if __name__=='__main__':
    main()
    c4d.EventAdd()
All

問題なく表示されました。

TP_MasterSystem.GetRootGroup() #ルートグループ「All」の取得
TP_PGroup.GetTitle() #グループの「名前」の取得

それでは、ビュータイプ等を取得してみましょう。

Python
'''
最上位のパーティクルグループを取得-2
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()
    print '名前:', root_gp.GetTitle()
    v_type = {c4d.PG_NONE:'なし',
                c4d.PG_FLAKES:'フレーク',
                c4d.PG_DOTS:'ドット',
                c4d.PG_TICKS:'ティック',
                c4d.PG_DROPS:'ドロップ',
                c4d.PG_BOX:'ボックス',
                c4d.PG_GLOBAL:'グローバル'}
    print 'ビュータイプ:', v_type[root_gp.GetViewType()]
    print 'カラー:', root_gp.GetColor()
    print 'オブジェクトを表示:', root_gp.GetShowObjects()
    print 'パーティクル数:', root_gp.NumParticles()


if __name__=='__main__':
    main()
    c4d.EventAdd()
名前: All
ビュータイプ: グローバル
カラー: Vector(1, 1, 1)
オブジェクトを表示: True
パーティクル数: 0

グループ「All」の設定値を取得することができました。

TP_PGroup.GetViewType() #グループの「ビュータイプ」の取得
TP_PGroup.GetColor() #グループの表示「カラー」の取得
TP_PGroup.GetShowObjects() #グループの「オブジェクトの表示」の取得
TP_PGroup.NumParticles() #グループ内のパーティクル数の取得

「All」以下のグループを取得し、設定値を表示してみます。

では、全てのグループを取得してみる。

Python
'''
全てのパーティクルグループを取得
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()
    gps = tp.GetParticleGroups(root_gp, c4d.TP_GETPGROUP_ALL)
    for gp in gps:
        print gp.GetTitle()


if __name__=='__main__':
    main()
    c4d.EventAdd()
Traceback (most recent call last):
  File "<scriptmanager>", line 16, in <module>
  File "<scriptmanager>", line 10, in main
SystemError: .\source\pymodules\c4d.modules\c4d.modules.thinkingparticles\PyTPGroup\PyTPGroup.cpp:341: bad argument to internal function

GetParticleGroups()でエラーを起こしています。

TP_MasterSystem.GetParticleGroups() #パラメータ設定で全てのグループ/選択されたグループ等を取得できるはずですが…

Python SDK Documentを見ても原因がわかりません…

どうしたら良いのかわかるユーザの方、こっそり教えてください…

仕方がないので…
GetParticleGroups()にパラメータを指定しないで使うことにした…

Python
'''
全てのパーティクルグループを取得-2
'''

import c4d

def main():
    if not tp: return

    gps = tp.GetParticleGroups()
    for gp in gps:
        print gp.GetTitle()


if __name__=='__main__':
    main()
    c4d.EventAdd()
All
グループ.1
グループ.2
グループ.3

GetParticleGroups()はパラメータ設定で、選択されたグループだけを取得できるはずなんだけど… 無理なのかなぁ… 残念だけど…

それでは、気を取り直して…
全てのグループの設定値を表示してみよう。

Python
'''
全てのパーティクルグループのデータを表示
'''

import c4d

def PrintGroupData(gp):
    print '='*5, gp.GetTitle(), '='*5
    v_type = {c4d.PG_NONE:'なし',
                c4d.PG_FLAKES:'フレーク',
                c4d.PG_DOTS:'ドット',
                c4d.PG_TICKS:'ティック',
                c4d.PG_DROPS:'ドロップ',
                c4d.PG_BOX:'ボックス',
                c4d.PG_GLOBAL:'グローバル'}
    print 'ビュータイプ:', v_type[gp.GetViewType()]
    print 'カラー:', gp.GetColor()
    print 'オブジェクトを表示:', gp.GetShowObjects()

    if gp.IsSelected():print '選択されているよ!!'

    print 'パーティクル数:', gp.NumParticles()
    print


def main():
    if not tp: return

    root_gp = tp.GetRootGroup()
    gps = tp.GetParticleGroups()
    for gp in gps:
        PrintGroupData(gp)


if __name__=='__main__':
    main()
    c4d.EventAdd()
===== All =====
ビュータイプ: グローバル
カラー: Vector(1, 1, 1)
オブジェクトを表示: True
パーティクル数: 0

===== グループ.1 =====
ビュータイプ: グローバル
カラー: Vector(1, 0, 0)
オブジェクトを表示: True
選択されているよ!!
パーティクル数: 19

===== グループ.2 =====
ビュータイプ: グローバル
カラー: Vector(1, 1, 0)
オブジェクトを表示: True
パーティクル数: 38

===== グループ.3 =====
ビュータイプ: グローバル
カラー: Vector(0, 1, 0)
オブジェクトを表示: True
パーティクル数: 57

グループが選択されているかも取得できているようだね…

TP_PGroup.IsSelected() #グループが選択されているか?

パーティクル数も取得できているね…

Python_tp_36

では、ルートグループ「All」の名前等を変更してみよう。

試しに、名前だけ変更してみる…

Python
'''
ルートのパーティクルグループ「All」の名前を変更
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()

    #名前の変更
    if root_gp.GetTitle() == 'All':
        root_gp.SetTitle('全て')
    else:
        root_gp.SetTitle('All')


if __name__=='__main__':
    main()
    c4d.EventAdd()

どうしてだろうか?
名前が変更されないなぁ…
SetTitle()が機能しないようだ…

TP_PGroup.SetTitle() #グループの「名前」の設定のはずですが…

仕方がないので…
TP_PGroupはc4d.BaseList2Dを継承しているので、SetName()を使って名前を変更してみる。

Python
'''
ルートのパーティクルグループ「All」の名前を変更-2
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()

    #名前の変更
    if root_gp.GetTitle() == 'All':
        root_gp.SetName('全て')
    else:
        root_gp.SetName('All')


if __name__=='__main__':
    main()
    c4d.EventAdd()

問題ないようですね…

Python_tp_38

では、他のデータも変更してみよう。

Python
'''
ルートのパーティクルグループ「All」のデータを変更
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()

    #名前の変更
    if root_gp.GetTitle() == 'All':
        root_gp.SetName('全て')
    else:
        root_gp.SetName('All')

    #ビュータイプの変更
    if root_gp.GetViewType() == c4d.PG_GLOBAL:
        root_gp.SetViewType(c4d.PG_FLAKES)
    else:
        root_gp.SetViewType(c4d.PG_GLOBAL)

    #カラーの変更
    root_gp.SetColor(c4d.Vector(1.0) - root_gp.GetColor())

    #オブジェクトの表示の変更
    root_gp.SetShowObjects(not root_gp.GetShowObjects())


if __name__=='__main__':
    main()
    c4d.EventAdd()

問題なく変更されました。

TP_PGroup.SetViewType() #グループの「ビュータイプ」の設定
TP_PGroup.SetColor() #グループの表示「カラー」の設定
TP_PGroup.SetShowObjects() #グループの「オブジェクトを表示」の設定

ビュータイプの定数は…

c4d.PG_NONE なし
c4d.PG_FLAKES フレーク
c4d.PG_DOTS ドット
c4d.PG_TICKS ティック
c4d.PG_DROPS ドロップ
c4d.PG_BOX ボックス
c4d.PG_GLOBAL グローバル

実行するたびに、Allグループの設定が変更されます。

Python_tp_37

次は…

グループIDと階層レベルを取得してみる。

Python_tp_16

Python
'''
全てのパーティクルグループのグループIDと階層レベルを表示
'''

import c4d

def main():
    if not tp: return

    gps = tp.GetParticleGroups()
    for gp in gps:
        print '='*5, gp.GetTitle(), '='*5
        print 'グループID:', gp.GetGroupID()
        print '階層レベル:', gp.GetLevel()
        print


if __name__=='__main__':
    main()
    c4d.EventAdd()
===== 全て =====
グループID: 0
階層レベル: 0

===== グループ.1 =====
グループID: 1
階層レベル: 1

===== グループ.2 =====
グループID: 2
階層レベル: 2

===== グループ.3 =====
グループID: 3
階層レベル: 2

これも、問題なさそうだ…

TP_PGroup.GetGroupID() #グループのIDの取得
TP_PGroup.GetLevel() #グループの階層レベルの取得

グループIDは上から順に振られているようだ。
階層レベルは、親の数でもあります。

忘れていましたが、グループ内のパーティクルを取得する。

Python
'''
全てのパーティクルグループのパーティクル数とパーティクル番号を表示
'''

import c4d

def main():
    if not tp: return

    gps = tp.GetParticleGroups()
    for gp in gps:
        print '='*5, gp.GetTitle(), '='*5
        print 'パーティクル数:', gp.NumParticles()
        print 'パーティクル:', gp.GetParticles()
        print


if __name__=='__main__':
    main()
    c4d.EventAdd()
===== 全て =====
パーティクル数: 0
パーティクル: []

===== グループ.1 =====
パーティクル数: 19
パーティクル: [5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89, 95, 101, 107, 113]

===== グループ.2 =====
パーティクル数: 38
パーティクル: [3, 4, 9, 10, 15, 16, 21, 22, 27, 28, 33, 34, 39, 40, 45, 46, 51, 52, 57, 58, 63, 64, 69, 70, 75, 76, 81, 82, 87, 88, 93, 94, 99, 100, 105, 106, 111, 112]

===== グループ.3 =====
パーティクル数: 57
パーティクル: [0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32, 36, 37, 38, 42, 43, 44, 48, 49, 50, 54, 55, 56, 60, 61, 62, 66, 67, 68, 72, 73, 74, 78, 79, 80, 84, 85, 86, 90, 91, 92, 96, 97, 98, 102, 103, 104, 108, 109, 110]

GetParticles()はパーティクルの取得ですが、実際には、パーティクル番号のリストの取得です。

TP_PGroup.GetParticles() #グループ内のパーティクルの取得

全部ではありませんが、ほぼTP_PGroupのメソッドを確認できたかと思う…

もしもC4D Pythonで新規のパーティクルグループを追加しなければいけなくなったら…

試しに、グループ「All」の最初の子グループとして新規のグループを挿入してみる。

Python
'''
新規パーティクルグループの挿入
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()
    new_gp = tp.AllocParticleGroup()
    tp.SetPGroupHierarchy(root_gp, new_gp, c4d.TP_INSERT_UNDERFIRST)


if __name__=='__main__':
    main()
    c4d.EventAdd()
Traceback (most recent call last):
  File "<scriptmanager>", line 15, in <module>
  File "<scriptmanager>", line 11, in main
SystemError: .\source\pymodules\c4d.modules\c4d.modules.thinkingparticles\PyTPGroup\PyTPGroup.cpp:341: bad argument to internal function

またも、エラーだ…

TP_MasterSystem.AllocParticleGroup() #パーティクルグループの割り当て
TP_MasterSystem.SetPGroupHierarchy() #パーティクルグループの挿入のはずですが…

SetPGroupHierarchy()が問題のようだ…
これもPython SDK Docを見てもわかりません。

ただし、TP_PGroupはc4d.BaseList2Dを継承しているので、GetDown()/GetNext()やInsertUnder()/InsertBefore()/InsertAfter()を使ってなんとかできるかと…

Python
'''
新規パーティクルグループの挿入-2
ルートグループの下にグループがあれば、更に下に新規のグループを追加。
ルートグループの下にグループがなければ、ルートグループの下に追加。
'''

import c4d

def main():
    if not tp: return

    root_gp = tp.GetRootGroup()
    new_gp = tp.AllocParticleGroup()
    gp = root_gp.GetDown()
    if gp:
        new_gp.InsertUnder(gp)
    else:
        new_gp.InsertUnder(root_gp)


if __name__=='__main__':
    main()
    c4d.EventAdd()

Python_tp_39

問題なく、挿入できました。

パーティクルグループの開放を試してみる。
必要のなくなったグループは削除した方が良いのか?

とりあえず、子グループの無いグループを解放してみるよ。
先ほど追加した、「パーティクルグループ」「グループ.2」「グループ.3」が消えるはず。

Python
'''
子グループの無いグループの削除
'''

import c4d

def main():
    if not tp: return

    gps = tp.GetParticleGroups()
    for gp in gps:
        if not gp.GetDown():
            tp.FreeParticleGroup(gp)


if __name__=='__main__':
    main()
    c4d.EventAdd()
Traceback (most recent call last):
  File "<scriptmanager>", line 16, in <module>
  File "<scriptmanager>", line 12, in main
SystemError: .\source\pymodules\c4d.modules\c4d.modules.thinkingparticles\PyTPGroup\PyTPGroup.cpp:341: bad argument to internal function

これもまたエラーだよ…

TP_MasterSystem.FreeParticleGroup() #パーティクルグループの開放のはずが…

使い方が間違っているのか?

削除も、別の方法でするしかないのか?

Python
'''
子グループの無いグループの削除
'''

import c4d

def main():
    if not tp: return

    gps = tp.GetParticleGroups()
    for gp in gps:
        if not gp.GetDown():
            gp.Remove()


if __name__=='__main__':
    main()
    c4d.EventAdd()

Python_tp_40

問題なく消えました…

このくらいにしておきます…

今回はスクリプトマネージャ(Python)で試しましたが、パーティクルの動きを操作するならPythonノードやPythonタグを使うことになるだろう…

|

« C4D ThinkingParticlesをホンの少しだけ再確認…TPGeneratorとPPass | トップページ | C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-2 »

コメント

コメントを書く



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




« C4D ThinkingParticlesをホンの少しだけ再確認…TPGeneratorとPPass | トップページ | C4D Python R12 テスト:C4D ThinkingParticlesとC4D Pythonと試行錯誤-2 »