オペレータは適用すると、削除するまで「オペレータ スタック」と呼ばれるスタック上に置かれます(オペレータは一般にスタックのフリーズ操作で削除されます)。 このスタックはオブジェクトの履歴も追跡するので、「コンストラクション ヒストリ」とも呼ばれます。 このオブジェクト モデルは、 ConstructionHistory オブジェクトへのアクセスを Primitive.ConstructionHistory プロパティを介して提供します。 これはオペレータにアクセスするためにコンストラクション ヒストリを列挙するときに使用できます。 詳細については、「オペレータ スタック」を参照してください。
オペレータへのポインタを取得したら、以下のメソッドを使用してオペレータの入力ポート(オペレータのデータ変更を制御する値)と出力ポート(制御されているパラメータなど)にアクセスできます。
オブジェクト モデル: Operator.InputPorts および Operator.OutputPorts
C++ API: Operator::GetInputPorts および Operator::GetOutputPorts
ポートから、ポートが接続されるオブジェクトへのポインタを取得できます。Port.Target2(オブジェクト モデル)および Port::GetTarget(C++ API)です。
SDK の場合、オペレータ スタックはコンストラクション ヒストリと呼ばれます。絶えず繰り返されるオブジェクへの変更をそれぞれ把握しているからです。つまり、オブジェクトをフリーズするまで、オブジェクトに適用した各オペレータを把握しているということです。 オペレータ スタックは以下の 4 つのコンストラクション モード領域に分類されます。
オペレータが適用されるとすぐにコンストラクション ヒストリが構築されます。このコンストラクション ヒストリには、上記の 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 ; }