オペレータとその他へのアクセス

 
 
 

オペレータは適用すると、削除するまで「オペレータ スタック」と呼ばれるスタック上に置かれます(オペレータは一般にスタックのフリーズ操作で削除されます)。 このスタックはオブジェクトの履歴も追跡するので、「コンストラクション ヒストリ」とも呼ばれます。 このオブジェクト モデルは、 ConstructionHistory オブジェクトへのアクセスを Primitive.ConstructionHistory プロパティを介して提供します。 これはオペレータにアクセスするためにコンストラクション ヒストリを列挙するときに使用できます。 詳細については、「オペレータ スタック」を参照してください。

オペレータで実現できる内容

オペレータへのポインタを取得したら、以下のメソッドを使用してオペレータの入力ポート(オペレータのデータ変更を制御する値)と出力ポート(制御されているパラメータなど)にアクセスできます。

ポートから、ポートが接続されるオブジェクトへのポインタを取得できます。Port.Target2(オブジェクト モデル)および Port::GetTarget(C++ API)です。

ヒント:

UI に入力ポートと出力ポートを表示するには、SDK Explorer([表示](View)[スクリプト](Scripting))を開き、オペレータをクリックしてからメインのコンテンツ ペインの上にある[Object Details]リンクをクリックします。

オペレータは、現在書き込み先のオブジェクトに応じて[Scene Explorer]に表示されるので(つまり、オペレータが作成または修正しているオブジェクトのオペレータ スタックに表示されるので)、[Scene Explorer]内の複数個所に同時に表示される場合があります。

オペレータ スタック

SDK の場合、オペレータ スタックはコンストラクション ヒストリと呼ばれます。絶えず繰り返されるオブジェクへの変更をそれぞれ把握しているからです。つまり、オブジェクトをフリーズするまで、オブジェクトに適用した各オペレータを把握しているということです。 オペレータ スタックは以下の 4 つのコンストラクション モード領域に分類されます。

領域名

説明

フルネームから戻される名前

モデリング

デフォーメーションとトポロジの両オペレータを使用して、オブジェクトの基本的なシェイプとトポロジを定義します。

modelingmarker

シェイプ モデリング

Cluster Shape Combiner ノードを格納します。また、シェイプ アニメーションのシェイプ キーを定義するためにデフォーメーションを適用できます。

shapemarker

アニメーション

モデリングのフリーズまたはシェイプの適用時に、アニメートされたデフォーメーションが削除されることを防ぎます。

animationmarker

2 次シェイプ モデリング

エンベロープされたキャラクタ上の筋肉バルジなどのシェイプ キーを作成するために使用します。

secondaryshapemarker

オペレータが適用されるとすぐにコンストラクション ヒストリが構築されます。このコンストラクション ヒストリには、上記の 4 つのマーカー以外に新しいオペレータも含まれます。 コンストラクション ヒストリ内のオペレータを列挙すると、これらの 4 つのマーカーはフルネームで報告されます(上の表の第 3 列目に記載している名前です)。したがって、希望のオペレータが実際に適用されているかどうかを確認するため、コンストラクション ヒストリの各アイテムをテストすることが可能です。

オペレータ スタック/コンストラクション ヒストリの操作

シーン オブジェクトに適用されるオペレータを検索するには、オブジェクトの ConstructionHistory のコンテンツを検索する必要があり、これは Primitive.ConstructionHistory プロパティからアクセスできます(コンストラクション モード領域からナビゲートする方法のスクリプト例については、「JScript の例: 特定のコンストラクション領域からのオペレータ選択」を参照してください)。

注:

現在、Primitive.ConstructionHistory プロパティはオブジェクト モデルでのみ使用できます。 ただし、CComAPIHandler を使用すると、C++ API プラグ インは Primitive に接続されたオペレータに到達することができます(たとえば、「C++ の例: CComAPIHandler を使ったコンストラクション ヒストリへのアクセス」を参照してください)。

JScriptの例: 特定のコンストラクション領域からのオペレータ選択

この例では、立方体を作成し、いくつかのオペレータを異なるコンストラクション モードで適用しています。 その後に、オペレータ スタックが読み取られています。そのため、アニメーション コンストラクション モード領域に分類されるオペレータのみが対象となっています。

// Set up a scene with a cube and apply a variety of deform operators
// in a variety of construction modes
NewScene( null, false );
var obj = CreatePrim( "Cube", "MeshSurface" );
ApplyOp( "Bulge", "cube", 3, siPersistentOperation, null, 0 );
ApplyOp( "Bend", "cube", 3, siPersistentOperation, null, 0 );
SetValue( "Context.ConstructionMode", 2 );
ApplyOp( "Fold", "cube", 3, siPersistentOperation, null, 2 );
ApplyOp( "Shear", "cube", 3, siPersistentOperation, null, 2 );
SetValue( "Context.ConstructionMode", 3 );
ApplyOp( "Smooth", "cube", 3, siPersistentOperation, null, 3 );


// Get the cube's operator stack/construction history and browse it...
var opstack = new Enumerator( obj.ActivePrimitive.ConstructionHistory );
var getanimops = false;
for ( ; !opstack.atEnd(); opstack.moveNext() ) {
	var op = opstack.item();
	Application.LogMessage( "Current node: " + op.FullName );

	// Use RegularExpression matching to identify the markers in the stack
	var beginregion = false;
	if ( op.FullName.match(/marker/i) != null ) {
		beginregion = true;
	} else {
		beginregion = false;
	}
	
	// Grab only animation operators
	if ( !beginregion && getanimops ) {
		Application.LogMessage( "\tFound this animation operator: " + op.Name );
	}
	
	// Figures out when we're in the Animation region
	if ( beginregion ) {
		if ( op.FullName.match(/animationmarker/i) != null ) {
			getanimops = true;
		} else {
			getanimops = false;
		}
	}
}

//INFO : Current node: cube.polymsh.secondaryshapemarker
//INFO : Current node: cube.polymsh.smoothop
//INFO : Current node: cube.polymsh.animationmarker
//INFO : Current node: cube.polymsh.shearop
//INFO : 	Found this animation operator: Shear Op
//INFO : Current node: cube.polymsh.foldop
//INFO : 	Found this animation operator: Fold Op
//INFO : Current node: cube.polymsh.shapemarker
//INFO : Current node: cube.polymsh.modelingmarker
//INFO : Current node: cube.polymsh.bendop
//INFO : Current node: cube.polymsh.bulgeop
//INFO : Current node: cube.polymsh.geom

C++ の例: CComAPIHandler を使ったコンストラクション ヒストリへのアクセス

この例では、コンストラクション ヒストリにアクセスするために CComAPIHandler オブジェクトを使用して、Primitive に接続されたオペレータの CRefArray を作成する方法を示します。

// Given an X3DObject (e.g. a mesh or nurbs), fills in an array with all the operators connected to its
// primitive.	This function is suitable for re-use in any plug-in that wants to access construction history
void GetOperators( X3DObject in_ops, CRefArray & out_ops )
{
	Primitive primitive = in_ops.GetActivePrimitive() ;
	CComAPIHandler comPrimitive( primitive.GetRef() ) ;

	CComAPIHandler constructionHistory = comPrimitive.GetProperty( L"ConstructionHistory" ) ;
	
	// Currently there isn't a "Count" or "Item" property on the ConstructionHistory 
	// scripting object, so we use Filter to find all operators
	CValue valOperatorCollection	;
	CValueArray args(3)	;
	args[1] = CValue( L"Operators" ) ;	// We want all operators (siOperatorFamily)
	constructionHistory.Call( L"Filter", valOperatorCollection, args ) ;
	

	// Now convert from a OperatorCollection object to a C++ CRefArray
	CComAPIHandler comOpColl = valOperatorCollection ;
	CValue cnt = comOpColl.GetProperty( L"Count" ) ;
	
	CRefArray ops( (LONG)cnt ) ;
	
	for ( LONG i=0 ; i<(LONG)cnt; i++ )
	{
		CValue outOp;
		CValueArray itemsArgs;
		itemsArgs.Add( i );
		comOpColl.Invoke(L"Item", CComAPIHandler::PropertyGet, outOp, itemsArgs);
	
		ops[i] = outOp ;
	}
	
	out_ops = ops ;
}