カスタムメニューのサンプル

 
 
 

カスタム メニューの例としては、次のものが提供されています。

ヒント:

また、簡単なメニュー プラグイン サンプル(VBScript、JScript および C++ で書かれたバージョン)は、Softimage SDK のインストール場所と一緒に格納されています。次の場所を確認してください。

%XSI_ROOT%/XSISDK/examples/menus

JScript の例: サブメニュー内部にサブメニューをネストする

この自己インストール メニュー プラグインの例では、サブメニューを深くネストする方法を示します。 ここで使用されているエントリは、メカニズムを示す空白のエントリです。

/* ------------------------------------------------------------------

		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;
}

JScript の例: メニュー コールバック項目でコマンド インスタンスをシミュレートする

この例は、標準 Softimage コマンドの各種フレーバ(インスタンス)を実装する自己インストール プラグインで、いくつかのコールバック メニュー項目を定義する方法を示します。

  1. $user/Application/Pluginsフォルダの中にスクリプト ファイルを作成して OpMenuInstances.js という名前を付けます。 これは、新しいカスタム メニューの JScript 実装が格納されるスクリプト ファイルです。

  2. 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;
    }
  3. 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 コマンドを既定値で呼び出す単純な実装。

    • OnApplyDeformOp2switchステートメントを使用して、メニュー項目の名前をテストする複雑な実装。名前に基づいて、特定のパラメータ値を使用して ApplyOp または ApplyKinematicOp のどちらかを呼び出し、場合によってはオペレータが適用された後に追加のタスクを実行します。

  4. OnApplyDeformOp コールバック用の単純な実装を記述します。

    function OnApplyDeformOp( in_ctxt )
    {
    	// Get the menu item name
    	var mnu_itm = in_ctxt.Source;
    
    	ApplyOp( mnu_itm.Name );
    	return true;
    }
  5. 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;
    }
  6. Init コールバックを使用して、[Apply Generator Operators]メニューを定義します。 このメニューの項目は、現在選択されている内容と関係のある、特定の状況下でのみ表示されます。

    • 選択された項目どうしのプリミティブ タイプが異なる場合、どの項目もメニューに追加されません。

    • サーフェイス メッシュが 2 つ以上選択された場合、メニューに追加されるのは[フィット]オペレータおよび[インターセクションのフィレット]オペレータだけです。

    • ポリゴン メッシュが 1 つだけ選択された場合、メニューに追加されるのは[サブディバイド]オペレータだけです。

    • ポリゴン メッシュが 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;
    }
  7. 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;
    }
  8. ファイルを保存して、Softimage を起動します。 Softimage がすでに実行されている場合、プラグイン マネージャを開き([ファイル](File)メニューから[プラグイン](Plug-ins)[マネージャ](Manager)を選択)、[更新](Update)ボタンをクリックして、このプラグインを明示的にロードすることができます。

  9. メニューをテストするには、いくつかのプリミティブを作成し選択して、[アプリケーション]メニューを開きます。 このメニューの下部に、次の新しいメニューが表示されます。

    • Apply Deform Operators[u]

    • Apply Generator Operators[u]