« C4D Python R12 テスト:スプラインセグメントの終端ポイント番号を取得してみる。 | トップページ | C4D Python R12 テスト:セグメントに分断されているスプラインを全部連結させようと… »

C4D Python R12 テスト:2個のスプラインを連結する。

スプラインを連結する、と言うのか…セグメントを連結する、と言うのか…

2本のスプラインを連結するには、2本のスプラインを選択して「一体化+消去」してから、連結する2つのポイントを選択して「セグメントを連結」をして完了です。

Python_splinejoint_01

これをC4D Pythonでするには…

GUIで2つのスプラインを選択して、連結する2つのポイントも選択。
それから、C4D Pythonスクリプトを実行するとスプラインが連結される。
と言う流れかな…

ちょっと確認。
2つのスプラインを選択した状態でポイントを選択し、「一体化 + 消去」をした後、ポイントの選択は解除されるのか?

Python_splinejoint_02

問題無いようだね。
「一体化 + 消去」後もポイントの選択は解除されないようだ。
そのまま、「セグメントを連結」をすれば完了だ。

C4D Pythonスクリプトは…
2つのスプラインをSendModelingCommand()で「一体化 + 消去」しようかと思ったら、無いのね…よく探したら、あったりして…
ま、仕方ないからCallCommand()でやるしかないのか…

「一体化 + 消去」後の一体化されたオブジェクトの取得は…?
「一体化 + 消去」後、一体化されたオブジェクトが選択状態にあるので、BaseDocument.GetSelection()でオブジェクトを取得する事にした。
BaseDocument.GetActiveObject()でも良いのね。でも、この場合はSendModelingCommand()でオブジェクトを指定する時に[ ]で括弧ってリスト型で…

「セグメントを連結」は、SendModelingCommand()にあるので問題ないだろう…
http://villager-and-c4d.cocolog-nifty.com/blog/2011/06/c4d-python-r-22.html

Python
'''
スプラインの連結
'''


import c4d
from c4d import utils


def main():

    c4d.CallCommand(16768) #一体化 + 消去
    obj = doc.GetSelection() #一体化されたオブジェクトの取得

    #セグメントを連結
    bc = c4d.BaseContainer()
    doc.StartUndo()
    utils.SendModelingCommand(c4d.MCOMMAND_SPLINE_JOINSEGMENT, obj,
                    c4d.MODELINGCOMMANDMODE_POINTSELECTION, bc, doc,
                    c4d.MODELINGCOMMANDFLAGS_CREATEUNDO)
    doc.EndUndo()


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

意外と短く…

CallCommand()を使っているので、Undoが思ったように記録できない。
「取消し」をしてもスクリプト実行前に戻らず、「セグメントを連結」前にしかもどれない。
もう一回「取消し」をしてやらないと、スクリプト実行前には戻れないね…
これは、仕方ないのか…?

まあ良いか…

それから、スプライン以外を選択されたりされると問題だよね…

じゃあ処理の除外対象を考えてみる。

選択オブジェクトが、2個以外だと終了
2つのオブジェクトがスプラインでなければ終了
2つのスプラインは開いていなければ終了
選択スプラインに1個づつ選択ポイントがなければ終了
2つの選択ポイントが、スプラインの終端でなければ終了

ま、こんな所だろうか…

スプラインの終端の取得は前回の記事

Python
'''
スプラインの連結
'''


import c4d
from c4d import utils


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

    pnt_cnt = obj.GetPointCount()
    if pnt_cnt == 0:return

    seg_cnt = obj.GetSegmentCount()
    if seg_cnt == 0:return [0, pnt_cnt - 1]

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

    return ends


#選択されたポイントが1個でスプラインの終端か調べる関数
def IsSplineEnds(obj):
    f = False
    if not isinstance(obj, c4d.SplineObject):return f

    sel = obj.GetPointS() #ポイント選択範囲の取得
    if sel.GetCount() != 1:return f #ポイントの選択数が1でなければFALSE
    ends = GetSplineEnds(obj) #終端の取得
    pt = 0
    while not sel.IsSelected(pt):pt += 1 #選択ポイントの取得
    for c in ends: #終端チェック
        if pt == c:
            f = True
            break
    return f #選択ポイントが終端だったらTRUE


def main():
    #選択オブジェクトが2個でなければ終了
    sel_obj = doc.GetSelection()
    if len(sel_obj) != 2:return

    #2個の選択オブジェクトがスプラインでなければ終了
    if not isinstance(sel_obj[0], c4d.SplineObject):return
    if not isinstance(sel_obj[1], c4d.SplineObject):return

    #2個のスプラインの内、どちらかが開いていれば終了
    if sel_obj[0].IsClosed():return
    if sel_obj[1].IsClosed():return

    #選択ポイントが1個でスプラインの終端でなければ終了
    if not IsSplineEnds(sel_obj[0]):return
    if not IsSplineEnds(sel_obj[1]):return


    #スプラインの一体化
    c4d.CallCommand(16768) #一体化 + 消去
    obj = doc.GetSelection() #一体化されたオブジェクトの取得

    #セグメントを連結
    bc = c4d.BaseContainer()
    doc.StartUndo()
    utils.SendModelingCommand(c4d.MCOMMAND_SPLINE_JOINSEGMENT, obj,
                    c4d.MODELINGCOMMANDMODE_POINTSELECTION, bc, doc,
                    c4d.MODELINGCOMMANDFLAGS_CREATEUNDO)
    doc.EndUndo()


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

いつもながら、行き当たりばったりな感じだね。

Python_splinejoint_03

これで、2個のスプラインを連結することができますが…
そう言えば、スプラインタイプは全く考えていませんでしてけど…
まあ良いか…

なんとなく投げやりな…

|

« C4D Python R12 テスト:スプラインセグメントの終端ポイント番号を取得してみる。 | トップページ | C4D Python R12 テスト:セグメントに分断されているスプラインを全部連結させようと… »

コメント

コメントを書く



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




« C4D Python R12 テスト:スプラインセグメントの終端ポイント番号を取得してみる。 | トップページ | C4D Python R12 テスト:セグメントに分断されているスプラインを全部連結させようと… »