CycleIDを変更した時に,連動してパラメータを同時に変更したい時,どのようにすればよいか考えてみました.
この例ではCycleに設定したアイテムとパラメータには特に意味があるわけではないですが,Matrix Typeを変更すると連動してMatrix Rootというユーザデータを変更させることにトライしました.
Cycle用のアイテムについてはBaseContainerとしたMatrixTypeItemsにSetStringを使用してIDとともに以下のように定義しています.
BaseContainer.SetString(id, s)
# Matrix Type Cycle Data
MatrixTypeItems = c4d.BaseContainer()
MatrixTypeItems.SetString( 0, "CINEMA 4D" )
MatrixTypeItems.SetString( 1, "3ds MAX" )
MatrixTypeItems.SetString( 2, "MAYA" )
MatrixTypeItems.SetString( 3, "Redqueen" )
Cycleはc4d.GetCustomDatatypeDefault(c4d.DTYPE_LONG)で作成します.さらにbcのDESC_CUSTOMGUIにDESC_CUSTOMGUI_CYCLEを代入します.SetContainerを使って,DESC_CYCLEにdata(先のCycle dataです)をセットし,それをAddUserData(bc)として追加しています.
bc = c4d.GetCustomDatatypeDefault(c4d.DTYPE_LONG)
bc[c4d.DESC_NAME] = cycleText
bc[c4d.DESC_CUSTOMGUI] = c4d.CUSTOMGUI_CYCLE
bc[c4d.DESC_PARENTGROUP] = parentGroup
bc.SetContainer(c4d.DESC_CYCLE, data)
self.Cycle[cycleId] = self.obj.AddUserData(bc)
プラグインを最初にメニューから呼び出したときにはInit関数により初期値が設定されているので,次に何かパラメータを変更した時(ここではCycleアイテムを変更した場合),連動してパラメータを変更するには,まずプラグインのパラメータが変更されたことを伝える必要があります.それがMessageという関数です.これらはNodeDataクラスに属しており,派生クラスのTagDataやObjectDataでも使うことができます.
NodeData.Message(self, node, type, data)
沢山のメッセージがあり,ノードにそれぞれのアクションメッセージを伝える役割があります.例えばオブジェクトデータが変更された時,ユーザが要素をダブルクリックした時,などがあります.今回はMSG_DESCRIPTION_CHECKUPDATEを使って,何かデータが変更されたことをノードに渡し,キューとして使います.
if type == c4d.MSG_DESCRIPTION_CHECKUPDATE:
CurrentCycleID = CurrentData
if OldCycleID != CurrentCycleID
# do something
self.ud.SetRootMatrix( Const.UI_MATRIX_DISPLAY_ROOT, cycleId )
として,何かデータが変更され,かつそれがCycleIDであれば,do somethingを実行するという流れです.ここでset_root_matrix関数を呼び出し,プラグインの初期化の際に作成したマトリックスのIDと新しいCycleIDを渡して,CycleIDに応じたマトリックスを代入します.
self.ud.SetRootMatrix( Const.UI_MATRIX_DISPLAY_ROOT, cycleId )
class UD ()
MatC4D = c4d.Matrix ( c4d.Vector(0, 0, 0),
c4d.Vector(1, 0, 0),
c4d.Vector(0, 1, 0),
c4d.Vector(0, 0, 1) )
Mat3dsMax...
def SetRootMatrix ( self, matrixId, cycleId ):
if (self.Matrix[matrixId]) is None:
print("matrixId is None")
else:
if cycleId == [0]: # If Cycle is Cinema4D
self.obj[self.Matrix[matrixId]] = UD.MatC4D
elif cycleId == [1]: # If Cycle is 3ds Max
self.obj[self.Matrix[matrixId]] = UD.Mat3dsMax
elif cycleId == [2]: # If Cycle is MAYA
self.obj[self.Matrix[matrixId]] = UD.MatMaya
elif cycleId == [3]: # If Cycle is Redqueen
self.obj[self.Matrix[matrixId]] = UD.MatRq
return self.Matrix
これで,CycleIDを変えることで連動してマトリックスを変更できました.(数値は適当です)