カスタム メニューの例としては、次のものが提供されています。
JScript の例: サブメニュー内部にサブメニューをネストする: AddItem メソッドを使用して 3 つまたは 4 つのレベルにわたってカスケード レベルを縮小させるサブメニューを作成する方法を示します。
JScript の例: メニュー コールバック項目でコマンド インスタンスをシミュレートする: 標準 Softimage コマンドの各種フレーバ(インスタンス)を実装する自己インストール プラグインで、いくつかのコールバック メニュー項目を定義する方法を示します。
この自己インストール メニュー プラグインの例では、サブメニューを深くネストする方法を示します。 ここで使用されているエントリは、メカニズムを示す空白のエントリです。
/* ------------------------------------------------------------------ This self-installing menu plug-in demonstrates how to nest submenus deeply. The entries used are just blank entries to demonstrate the mechanism. */ /* ------------------------------------------------------------------ ### REGISTRATION ### */ function XSILoadPlugin( in_reg ) { // Set up some basic information for the whole plug-in in_reg.Name = "Nested Demo"; in_reg.Author = "Softimage SDK Education"; in_reg.Email = "editors@softimage.com"; in_reg.URL = "http://www.softimage.com/education"; in_reg.Major = 1; in_reg.Minor = 0; // Register a single Menu entry point on the Help menu in_reg.RegisterMenu( siMenuMainHelpID, "NestedMenus" ); // Only the first level is flat; the submenus still cascade on // the Window menu in_reg.RegisterMenu( siMenuMainWindowID, "NestedMenus", false ); // This one will stick all submenus on the same level on the Layers // contextual menu in_reg.RegisterMenu( siMenuSELayersContextID, "FlatMenus" ); // You can also log a message about this plug-in's installation Application.LogMessage( "The 'Nested Demo' plug-in has been " + "successfully installed." ); // Finish with success notification return true; } /* ------------------------------------------------------------------ ### DEFINITION ### This menu definition creates a cascading menu effect with several submenus nested inside the next one. */ function NestedMenus_Init( in_context ) { // Get the menu object from the Context input var oTopMnu = in_context.Source; // Add some regular menu items oTopMnu.AddItem( "Regular Item1", siMenuItem ); oTopMnu.AddItem( "Regular Item2", siMenuItem ); // Add the submenu item var oSubLevel1 = oTopMnu.AddItem( "SubMenu Demo Level1", siMenuItemSubmenu ) oSubLevel1.AddItem( "SubLevel1 ItemA", siMenuItem ); oSubLevel1.AddItem( "SubLevel1 ItemB", siMenuItem ); // Nest another submenu item var oSubLevel2 = oSubLevel1.AddItem( "SubMenu Demo Level2", siMenuItemSubmenu ) oSubLevel2.AddItem( "SubLevel2 ItemA", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemB", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemC", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemD", siMenuItem ); // ...and another ... var oSubLevel3 = oSubLevel2.AddItem( "SubMenu Demo Level3", siMenuItemSubmenu ) oSubLevel3.AddItem( "SubLevel3 ItemA", siMenuItem ); oSubLevel3.AddItem( "SubLevel3 ItemB", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemC", siMenuItem ); // ,,, etc. // Finish with success notification return true; } /* ------------------------------------------------------------------ ### DEFINITION ### This menu definition creates a several submenus appearing as siblings. */ function FlatMenus_Init( in_context ) { // Get the menu object from the Context input var oTopMnu = in_context.Source; // Add some regular menu items oTopMnu.AddItem( "Regular Item1", siMenuItem ); oTopMnu.AddItem( "Regular Item2", siMenuItem ); // Add a submenu item var oSubLevel1 = oTopMnu.AddItem( "SubMenu Demo Level1", siMenuItemSubmenu ) oSubLevel1.AddItem( "SubLevel1 ItemA", siMenuItem ); oSubLevel1.AddItem( "SubLevel1 ItemB", siMenuItem ); // And another submenu item var oSubLevel2 = oTopMnu.AddItem( "SubMenu Demo Level2", siMenuItemSubmenu ) oSubLevel2.AddItem( "SubLevel2 ItemA", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemB", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemC", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemD", siMenuItem ); // ...and another ... var oSubLevel3 = oTopMnu.AddItem( "SubMenu Demo Level3", siMenuItemSubmenu ) oSubLevel3.AddItem( "SubLevel3 ItemA", siMenuItem ); oSubLevel3.AddItem( "SubLevel3 ItemB", siMenuItem ); oSubLevel2.AddItem( "SubLevel2 ItemC", siMenuItem ); // ,,, etc. // Finish with success notification return true; }
この例は、標準 Softimage コマンドの各種フレーバ(インスタンス)を実装する自己インストール プラグインで、いくつかのコールバック メニュー項目を定義する方法を示します。
$user/Application/Pluginsフォルダの中にスクリプト ファイルを作成して OpMenuInstances.js という名前を付けます。 これは、新しいカスタム メニューの JScript 実装が格納されるスクリプト ファイルです。
2 つのカスタム メニューが組み込まれた登録コールバックを[アプリケーション](Application)メニューに表示されるようにセットアップします。2 つのカスタム メニューのうち、1 つは[ジェネレータ]オペレータ インスタンスを含み、もう 1 つは[デフォーム]オペレータ インスタンスを含みます。
function XSILoadPlugin( in_reg ) { // Register the plug-in information in_reg.Author = "Softimage Corp."; in_reg.Name = "Submenu command example"; // Set the version number of this plugin in_reg.Major = 1; in_reg.Minor = 0 ; // Register the Deform menu in the Application menu in_reg.RegisterMenu( siMenuMainApplicationID, "ApplyDeformOp_Menu" ); // Register the Generator menu in the Application menu in_reg.RegisterMenu( siMenuMainApplicationID, "ApplyGenOp_Menu" ); LogMessage( in_reg.Name + " has been loaded." ); return true; }
Init コールバックを使用して、[Apply Deform Operators]メニューを定義します。 このメニューの項目は、現在選択されている内容に関係なく、常に表示されます。 このメニューは、次の 3 つのセクションから構成され、各セクションはメニュー セパレータ バーで区切られています。
function ApplyDeformOp_Menu_Init( in_ctxt ) { var menu = in_ctxt.source; menu.Name = "Apply Deform Operators"; menu.AddCallbackItem( "Twist", "OnApplyDeformOp" ); menu.AddCallbackItem( "Bend", "OnApplyDeformOp" ); menu.AddCallbackItem( "Bulge", "OnApplyDeformOp" ); menu.AddCallbackItem( "Shear", "OnApplyDeformOp" ); menu.AddCallbackItem( "Taper", "OnApplyDeformOp" ); menu.AddSeparatorItem(); menu.AddCallbackItem( "Expand", "OnApplyDeformOp2" ); menu.AddCallbackItem( "Contract", "OnApplyDeformOp2" ); menu.AddSeparatorItem(); menu.AddCallbackItem( "Randomize", "OnApplyDeformOp2" ); menu.AddCallbackItem( "Relax", "OnApplyDeformOp2" ); menu.AddCallbackItem( "Smooth", "OnApplyDeformOp2" ); menu.AddCallbackItem( "QStretch", "OnApplyDeformOp2" ); return true; }
このメニューに使用されているコールバックは、次の 2 つです。
OnApplyDeformOp: オペレータの名前を取り(メニュー項目の名前として使用される)、ApplyOp コマンドを既定値で呼び出す単純な実装。
OnApplyDeformOp2:switchステートメントを使用して、メニュー項目の名前をテストする複雑な実装。名前に基づいて、特定のパラメータ値を使用して ApplyOp または ApplyKinematicOp のどちらかを呼び出し、場合によってはオペレータが適用された後に追加のタスクを実行します。
OnApplyDeformOp コールバック用の単純な実装を記述します。
function OnApplyDeformOp( in_ctxt ) { // Get the menu item name var mnu_itm = in_ctxt.Source; ApplyOp( mnu_itm.Name ); return true; }
OnApplyDeformOp2 コールバック用の複雑な実装を記述します。
function OnApplyDeformOp2( in_ctxt ) { // Get the menu item name var mnu_itm = in_ctxt.Source; switch (mnu_itm.Name) { case "Randomize" : // You can specify extra arguments ApplyOp( "Randomize", null, siBranch ); break; case "Expand" : // You could run extra commands to tweak the result... var op = ApplyOp( "Push" )(0); op.ampl.Value = 2; break; case "Contract" : // ...and make slight changes var op = ApplyOp( "Push" )(0); op.ampl.Value = -2; break; case "QStretch" : // You can call a different command ApplyKinematicOp( "QStretch", null, siBranch ); break; case "Punch Out Shape" : ApplyOp( "QStretch", null, siBranch ); break; default : // This will catch "Relax" and "Smooth" ApplyOp( mnu_itm.Name ); } return true; }
Init コールバックを使用して、[Apply Generator Operators]メニューを定義します。 このメニューの項目は、現在選択されている内容と関係のある、特定の状況下でのみ表示されます。
サーフェイス メッシュが 2 つ以上選択された場合、メニューに追加されるのは[フィット]オペレータおよび[インターセクションのフィレット]オペレータだけです。
ポリゴン メッシュが 2 つ以上選択された場合、[ブール]オペレータ、[ブレンド]オペレータおよび[サブディバイド]オペレータがメニューに追加されます。
この条件メニューのコンストラクションは、メニューがダイナミックな場合にのみ機能します(つまり、RegisterMenu(PluginRegistrar)メソッドが Dynamic 引数に既定値 true を使用する場合)。詳細については「ユーザ メニューの内容は固定されているか」」を参照してください。
function ApplyGenOp_Menu_Init( in_ctxt ) { var menu = in_ctxt.source; menu.Name = "Apply Generator Operators"; // Make all selected objects are the same type var primtype = ""; for ( var i=0; i<Selection.Count; i++ ) { if ( primtype == "" ) { primtype = Selection(i).Type; } else { if ( primtype != Selection(i).Type ) { return false; } } } // Build the menu items according to the primitive type of the // selected objects switch (primtype) { case siSrfMeshPrimType : // Only display operator types that can be applied to surfmeshes if ( Selection.Count > 1 ) { // Make sure at least two items are selected menu.AddCallbackItem( "Fit to Shape", "OnApplyGenOp" ); menu.AddCallbackItem( "Fillet Intersection", "OnApplyGenOp" ); } break; case siPolyMeshType : // Only display operator types that can be applied to polymeshes if ( Selection.Count > 1 ) { // Make sure at least two items are selected for boolean operations menu.AddCallbackItem( "Punch Out Shape (Difference)", "OnApplyGenOp" ); menu.AddCallbackItem( "Leave Remainder Shape (Intersection)", "OnApplyGenOp" ); menu.AddCallbackItem( "Bind Shapes Together (Union)", "OnApplyGenOp" ); menu.AddCallbackItem( "Blend Shapes (Mesh)", "OnApplyGenOp" ); } menu.AddCallbackItem( "Subdivide Selection", "OnApplyGenOp" ); break; } return true; }
OnApplyGenOp コールバック用の単純な実装を記述します。 Init コールバックは選択に関するテストをすべて実行した後で、特定のコールバックを有効化します。このため、選択されたタイプが入力オブジェクトに適したものかどうかをこのコールバックでチェックする必要はありません。その選択に適合しないコマンドはすべてフィルタで除外されているためです。
function OnApplyGenOp( in_ctxt ) { // Get the menu item name var mnu_itm = in_ctxt.Source; switch (mnu_itm.Name) { case "Punch Out Shape (Difference)" : ApplyGenOp( "BooleanGenDifference", "", "", null, siImmediateOperation, siDeleteGenOpInputs ); break; case "Leave Remainder Shape (Intersection)" : ApplyGenOp( "BooleanGenIntersection", "", "", null, siImmediateOperation, siDeleteGenOpInputs ); break; case "Bind Shapes Together (Union)" : ApplyGenOp( "BooleanGenUnion", "", "", null, siImmediateOperation, siDeleteGenOpInputs ); break; case "Subdivide Selection" : MeshSubdivideWithCenter( null, "", null, siImmediateOperation, siDeleteGenOpInputs ); break; case "Fit to Shape" : ApplyGenOp( "SrfFit", "", "", null, siImmediateOperation, siDeleteGenOpInputs ); break; case "Fillet Intersection" : ApplyGenOp( null, "", "", null, siImmediateOperation, siDeleteGenOpInputs ); break; case "Blend Shapes (Mesh)" : ApplyGenOp( "MeshBlend", "", "", null, siImmediateOperation, siDeleteGenOpInputs ); break; default : } return true; }
ファイルを保存して、Softimage を起動します。 Softimage がすでに実行されている場合、プラグイン マネージャを開き([ファイル](File)メニューから[プラグイン](Plug-ins)[マネージャ](Manager)を選択)、[更新](Update)ボタンをクリックして、このプラグインを明示的にロードすることができます。
メニューをテストするには、いくつかのプリミティブを作成し選択して、[アプリケーション]メニューを開きます。 このメニューの下部に、次の新しいメニューが表示されます。