v4.0
on-the-fly のカスタムプロパティのレイアウトに関連付けられているスクリプトコードを含むString値を戻したり、設定したりします。このスクリプトコードには、プロパティページのイベントに反応するサブルーチンが含まれます。これは、SPDL ファイルの BeginScript/EndScript セクション(または同等の Logic セクション)で見られるテキストに相当します。
PPGLayout.Language セクションに指定されている言語で正しい書式のスクリプトを記述してください。このプロパティのコール時にはスクリプトの構文エラーがチェックされません。
ロジックスクリプトはサポートされているスクリプト言語で実装されたサブルーチンで構成されます。OnInit という名前のルーチンが定義されている場合、このルーチンは PPG が初めてロードされるときに呼び出されます。パラメータ変更に反応させるには、PARAMSCRIPTNAME_OnChanged という名前にprefixを付けて(処理中のカスタムプロパティではオプション。プラグインのプロパティ名ではデフォルト)、ルーチンを作成します。ボタンの押下時に実行されるスクリプトコードを記述する場合は、BUTTONNAME_OnClicked を作成します(同じ prefixing の規則が適用されます)。これらのすべてのルーチンにおいてコンテキスト情報を取得するには、オブジェクトPPGのグローバルインスタンスを使用します。
注:処理中のカスタムプロパティにある他のルーチンとの衝突を避けるため、siUILogicPrefix 属性を使用してプリフィックスを指定できます。これはプラグインベースのカスタムプロパティにこれらのイベントハンドラを指定する方法とは異なります。プラグインベースの場合は、デフォルトでプロパティ名がプリフィックスとして使用されます。プラグイン ベースおよび処理中のイベント ハンドラの命名との相違の詳細については、「Using Prefixes with Custom Properties」および「Naming Plug-in Items」を参照してください。
このプロパティにより、関連付けられている SPDL ファイルがなくともカスタムオブジェクトのプロパティページイベントハンドリングを保持できます。たとえば、文字列内にスクリプトファイルを読み込み、このプロパティの値として指定することもできます。
このプロパティを使用して PPGLayout に直接スクリプトコードを組み込まずに、siUILogicFile 属性を使用して外部ファイルを指定する方法もあります。PPGLayout.SetAttributeを参照してください。
CustomProperty に基づいている PluginItem の場合は、このプロパティを設定する必要はありません。この場合は、Plugin を実装する同一スクリプトファイルにイベントハンドリングコールバックを直接書き込めます(PluginRegistrar.RegisterProperty を参照)。
// get accessor String rtn = PPGLayout.Logic; // set accessor PPGLayout.Logic = String; |
/* This script demonstrates how it is possible to create a modal dialog box from scripting to ask a user a question. It then generates a simple skeleton based on the number of bones and positions requested by the user. Key points of this example: (1) Advantage of Object Model API over SPDL files. Because "for" loops can be used to dynamically add as many parameters are necessary it is easy to handle a variable number of options. For instance, this example can be changed to support 10 bone skeletons instead of 5 bone skeletons by changing a single variable. (2) Single script file takes care the entire plug-in (3) Logic code can be added to dynamically change the layout in response to the user's actions. This replaced the need for "spdl logic". (4) JScript's ability to get the source code associated with a function using the toString() property. */ g_maxbones = 5 ; Main() ; function Main() { var oPSet = CreatePSet() ; // We're going to take some of the routines in the script and // inject the code into the PPG layout, using the convenient // toString() method of JScript // Alternatively we could have saved that code as a separate // file var oLayout = oPSet.PPGLayout oLayout.Logic = OnInit.toString() + BoneNumber_OnChanged.toString() + CreateLayout.toString() + AddXYZRow.toString() ; oLayout.Language = "JScript" ; if ( !InspectObj( oPSet, null, null, siModal, false ) ) { CreateBones( oPSet ) ; } // Erase the temporary pset DeleteObj( oPSet ) ; } function CreatePSet() { var oPSet = ActiveSceneRoot.AddProperty( "CustomProperty", false, "Create_Bones_SDK_Example" ) ; // Default number of bones is three oPSet.AddParameter3( "BoneNumber", siInt4, 3 ) ; oPSet.AddParameter3( "origin_x", siDouble, 0 ) ; oPSet.AddParameter3( "origin_y", siDouble, 0 ) ; oPSet.AddParameter3( "origin_z", siDouble, 0 ) ; // Start bone numbering at "1" instead of 0 for usability for ( i = 1 ; i <= g_maxbones ; i++ ) { // We use a simple naming scheme. // e.g. "b4_x" is the "x" axis of bone 4. oPSet.AddParameter3( "b" + i.toString() + "_x", siDouble, i ) ; oPSet.AddParameter3( "b" + i.toString() + "_y", siDouble, i ) ; oPSet.AddParameter3( "b" + i.toString() + "_z", siDouble, i ) ; } // None of the parameters are animatable - we are only using them // temporarily for the UI for ( i = 0 ; i < oPSet.Parameters.Count ; i++ ) { oPSet.Parameters(i).Animatable = false ; } return oPSet ; } // Do the work based on the values the user has entered in the // Custom Property function CreateBones( oPSet ) { // There must always be at least 1 bone oChainRoot = ActiveSceneRoot.Add3DChain( new Array( oPSet.origin_x.Value, oPSet.origin_y.Value, oPSet.origin_z.Value ), new Array( oPSet.b1_x.Value, oPSet.b1_y.Value, oPSet.b1_z.Value ) ) ; // Create a variable number of additional bones for ( i = 2 ; i <= oPSet.BoneNumber.Value ; i++ ) { strBoneName = "b" + i.toString() ; oChainRoot.AddBone( Array( oPSet.Parameters( strBoneName + "_x" ).Value, oPSet.Parameters( strBoneName + "_y" ).Value, oPSet.Parameters( strBoneName + "_z" ).Value ) ) ; } } // Event logic section - this code gets injected as part of the layout // Hence it can't rely on any global variables or other functions. function OnInit() { // Create the initial layout, based on the // default number of bones BoneNumber_OnChanged() } function BoneNumber_OnChanged() { // Redraw the UI, showing only controls // relevant to the number of Bones selected in the drop down CreateLayout(PPG.BoneNumber.Value ); PPG.Refresh() ; } function CreateLayout( in_cntBones ) { var oLayout = PPG.PPGLayout ; oLayout.Clear() ; // Flush old layout var oItem = oLayout.AddEnumControl( "BoneNumber", Array( "One", 1, "Two", 2, "Three", 3, "Four", 4, "Five", 5 ), siControlCombo ) oItem.Label = "Number of Bones" ; oLayout.AddGroup( "Bone Positions" ); AddXYZRow( oLayout, "Origin", "origin_x", "origin_y", "origin_z" ) ; for ( i = 1 ; i <= in_cntBones ; i++ ) { strOfI = i.toString() ; AddXYZRow( oLayout, "Bone " + strOfI, "b" + strOfI + "_x", "b" + strOfI + "_y", "b" + strOfI + "_z" ) ; } oLayout.EndGroup() ; } // Add a XYZ vector of parameters to the layout function AddXYZRow( in_Layout, in_Label, in_xName, in_yName, in_zName ) { in_Layout.AddGroup( in_Label ) ; in_Layout.AddRow(); oItem = in_Layout.AddItem( in_xName ) ; oItem.SetAttribute( siUIValueOnly, true ) ; oItem.SetAttribute( siUINoSlider, true ) ; oItem = in_Layout.AddItem( in_yName ) ; oItem.SetAttribute( siUIValueOnly, true ) ; oItem.SetAttribute( siUINoSlider, true ) ; oItem = in_Layout.AddItem( in_zName ) ; oItem.SetAttribute( siUIValueOnly, true ) ; oItem.SetAttribute( siUINoSlider, true ) ; in_Layout.EndRow() ; in_Layout.EndGroup() ; } |