« C4D Python R12 テスト:構造メニューの「スプラインを編集」のSendModelingCommand()を試してみた。 | トップページ | C4D Python R12 テスト:2個のスプラインを連結する。 »

C4D Python R12 テスト:スプラインセグメントの終端ポイント番号を取得してみる。

スプラインのセグメントの終端が必要になった事は無いだろうか?

Python_splinesegmentend_02

今回は、終端ポイント番号のリストとして取得する関数を作ってみる。

[0, 3, 4, 6, 7, 9]

こんな具合で…

まず試しに…

Python
'''
スプラインオブジェクトのセグメントを取得してコンソール表示
'''


import c4d


def main():
    if not isinstance(op, c4d.SplineObject):return

    print 'オブジェクト名:', op.GetName()

    seg_cnt = op.GetSegmentCount()
    print 'セグメント数:', seg_cnt

    for id in xrange(seg_cnt):
        print id, op.GetSegment(id)


if __name__ == '__main__':
    main()
オブジェクト名: スプライン
セグメント数: 3
0 {'cnt': 4, 'closed': False}
1 {'cnt': 3, 'closed': False}
2 {'cnt': 3, 'closed': False}

取得したセグメントの'cnt'を見るとわかるとおり、
セグメント0のポイント数は、4個
セグメント1、2は、それぞれ3個

このセグメントポイント数から、終端のポイント番号を取得してみよう。

Python_splinesegmentend_01

セグメント0の終端は…
開始端、0
終了端、セグメント0のポイント数(4) - 1 = (3)

セグメント1の終端は…
開始端、セグメント0のポイント数(4)
終了端、セグメント0のポイント数(4) + セグメント1のポイント数(3) - 1 = (6)

セグメント2の終端は…
開始端、セグメント0のポイント数(4) + セグメント1のポイント数(3) = (7)
週両端、セグメント0のポイント数(4) + セグメント1のポイント数(3) + セグメント2のポイント数(3) - 1 = (9)

単純で簡単だね。
セグメントが何個増えても単純に繰り返すだけ…

まずは試しに、取得したセグメントからセグメントポイント数を取得してみる。

Python
'''
スプラインオブジェクトのセグメントのポイント数を取得してコンソール表示
'''


import c4d


def main():
    if not isinstance(op, c4d.SplineObject):return

    print 'オブジェクト名:', op.GetName()

    seg_cnt = op.GetSegmentCount()
    print 'セグメント数:', seg_cnt

    for id in xrange(seg_cnt):
        print id, op.GetSegment(id)['cnt'] #<--- ここを修正


if __name__ == '__main__':
    main()
オブジェクト名: スプライン
セグメント数: 3
0 4
1 3
2 3

SplineObject.GetSegment()メソッドでセグメントを取得すると、辞書型で返ってくるので、キー'cnt'で格納されているポイント数を取得する。
取得できているね。

とりあえず、終端のポイント番号を取得してみよう…

Python
'''
スプラインオブジェクトのセグメントの終端番号を算出してコンソール表示
'''


import c4d


def main():
    if not isinstance(op, c4d.SplineObject):return

    print 'オブジェクト名:', op.GetName()

    seg_cnt = op.GetSegmentCount()
    print 'セグメント数:', seg_cnt

    sum = 0
    for id in xrange(seg_cnt):
        print sum #<--- ここを修正
        sum += op.GetSegment(id)['cnt'] #<--- ここを修正
        print sum - 1 #<--- ここを修正


if __name__ == '__main__':
    main()
オブジェクト名: スプライン
セグメント数: 3
0
3
4
6
7
9

問題ないようだ。

後は、関数にしてスプラインオブジェクトを渡したら終端ポイント番号をリストにして返すようにすれば良いんだよね。

Python
'''
スプラインオブジェクトのセグメントの終端番号を算出してコンソール表示
'''


import c4d


#スプラインのセグメントの終端を取得する関数
def GetSplineSegmentEnds(obj):
    if not isinstance(obj, c4d.SplineObject):return

    seg_cnt = obj.GetSegmentCount()
    ends = []
    sum = 0
    for id in xrange(seg_cnt):
        ends.append(sum)
        sum += obj.GetSegment(id)['cnt']
        ends.append(sum - 1)

    return ends


def main():
    if not isinstance(op, c4d.SplineObject):return

    print 'オブジェクト名:', op.GetName()

    seg_cnt = op.GetSegmentCount()
    print 'セグメント数:', seg_cnt

    print GetSplineSegmentEnds(op)


if __name__ == '__main__':
    main()
オブジェクト名: スプライン
セグメント数: 3
[0, 3, 4, 6, 7, 9]

問題なく取得できているね。

カラのリストにジャンジャン終端をappend()メソッドを使って追加していくのだ。
追加し終わったらリストを返すのだ。

これで、本当に良いのか?
そうでもないのだ…

試しに、新規でスプラインを1本作ってスクリプトを実行してみる。

Python_splinesegmentend_03

適当にスプラインを書いて…
書きたてのホカホカのスプラインでスクリプト実行してみる。

オブジェクト名: スプライン
セグメント数: 0
[]

セグメント数は0…
返ってきたリストはカラ…
本当は[0, 8]が返ってきてほしいところだけど…

出来立てのスプラインには、セグメント情報が無いのだ。
この関数のforループは実行されないのだ。

仮に、セグメント情報の無いスプラインに対して、GetSegment()メソッドにid:0で取得しようとしてもエラーが出てしまう。

IndexError: Segment index out of range.

セグメント数が0に限って、GetPointCount()メソッドを使ってスプラインの総ポイント数から終端を決めることにする。

Python
'''
スプラインオブジェクトのセグメントの終端番号を算出してコンソール表示--2
'''


import c4d


#スプラインのセグメントの終端を取得する関数
def GetSplineSegmentEnds(obj):
    if not isinstance(obj, c4d.SplineObject):return

    seg_cnt = obj.GetSegmentCount()

    #セグメント数が0の場合
    if seg_cnt == 0:
        return [0, obj.GetPointCount() - 1] #<--- ここを追加

    #セグメント数が0以外の場合
    ends = []
    sum = 0
    for id in xrange(seg_cnt):
        ends.append(sum)
        sum += obj.GetSegment(id)['cnt']
        ends.append(sum - 1)

    return ends


def main():
    if not isinstance(op, c4d.SplineObject):return

    print 'オブジェクト名:', op.GetName()

    seg_cnt = op.GetSegmentCount()
    print 'セグメント数:', seg_cnt

    print GetSplineSegmentEnds(op)


if __name__ == '__main__':
    main()
オブジェクト名: スプライン
セグメント数: 0
[0, 8]

問題ないね…

ちなみにね、「セグメントを連結」とか、編集後セグメントが1つになった場合、GetSegmentCount()メソッドはセグメント数1を返し、GetSegment()メソッドにid0を指定してもエラーは起こらないんだ。

最初のスプラインを連結してスクリプトを実行してみる。

Python_splinesegmentend_04

オブジェクト名: スプライン
セグメント数: 1
[0, 9]

セグメント数が1になっているよね。
終端も問題なく取得できている。

じゃあ、これで完成か?
そうでもないよね…

ポイント数が0のスプラインがあるよね。
空っぽのスプラインが…

空っぽのスプラインを渡すと…

オブジェクト名: スプライン
セグメント数: 0
[0, -1]

終端リストに -1 が含まれて…
空っぽのスプラインを渡さなければ良いんだけどね…

Python
'''
スプラインオブジェクトのセグメントの終端番号を算出してコンソール表示--3
'''


import c4d


#スプラインのセグメントの終端を取得する関数
def GetSplineSegmentEnds(obj):
    if not isinstance(obj, c4d.SplineObject):return

    pnt_cnt = obj.GetPointCount() #<--- ここを追加

    #ポイント数が0の場合
    if pnt_cnt == 0:return #<--- ここを追加

    seg_cnt = obj.GetSegmentCount()

    #セグメント数が0の場合
    if seg_cnt == 0:
        return [0, pnt_cnt - 1] #<--- ここを修正

    #セグメント数が0以外の場合
    ends = []
    sum = 0
    for id in xrange(seg_cnt):
        ends.append(sum)
        sum += obj.GetSegment(id)['cnt']
        ends.append(sum - 1)

    return ends


def main():
    if not isinstance(op, c4d.SplineObject):return

    print 'オブジェクト名:', op.GetName()

    seg_cnt = op.GetSegmentCount()
    print 'セグメント数:', seg_cnt

    print GetSplineSegmentEnds(op)


if __name__ == '__main__':
    main()
オブジェクト名: スプライン.2
セグメント数: 0
None

ポイント数が0の場合、Noneになるわけだ…
スプライン以外のオブジェクトもNoneになりますけどね。

Noneじゃなく、カラのリストを返したほうが良いのかなぁ…

あ…
セグメント番号を指定して、そのセグメントの終端を取得する関数の方が良いんじゃないか?

ま、今回は、これでヨシとしよう…

|

« C4D Python R12 テスト:構造メニューの「スプラインを編集」のSendModelingCommand()を試してみた。 | トップページ | C4D Python R12 テスト:2個のスプラインを連結する。 »

コメント

コメントを書く



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




« C4D Python R12 テスト:構造メニューの「スプラインを編集」のSendModelingCommand()を試してみた。 | トップページ | C4D Python R12 テスト:2個のスプラインを連結する。 »