C# でのオブジェクト モデル メソッドの使い方は非常に簡単ですが、いくつか注意すべき点があります。
C# では既定の引数をサポートしていません。このため、C# から OM メソッドを呼び出すときに、すべての引数を指定する必要があります。 たとえば以下のようになります。
app.LogMessage(str, siSeverity.siInfo);
スクリプティングでは siInfo 値がデフォルトですが、C# では明示的に指定する必要があります。
汎用的な C# オブジェクト クラス(Variant と等価)と out キーワード(これにより出力変数としてフラグされる)で宣言された変数を渡せば、メソッドから出力引数にアクセスできます。 メソッドが実行された後、この例で示すように、オブジェクトを正しい Softimage クラスにキャストするだけです。
// Set up the scene
CXSIApplicationClass app = new CXSIApplicationClass();
object[] args = new object[2] { "", false };
app.ExecuteCommand("NewScene", args);
Model root = app.ActiveSceneRoot;
X3DObject cube = root.AddGeometry("Cube", "MeshSurface", "MyCube");
// Start with a Phong, then reconnect a Lambert using Parameter.ConnectFromFile
Material mat = cube.AddMaterial("Phong", false, "MyPhong");
Parameter surface = mat.Parameters["Surface"];
app.LogMessage("currently connected shader: " + surface.Source.FullName, siSeverity.siInfo);
// Declare output arguments as a generic object and use the 'out' keyword
Object oldone;
DataSource lambert = surface.ConnectFromFile("$SI_HOME\\Data\\DSPresets\\Shaders\\Material\\Lambert.Preset", out oldone);
app.LogMessage("currently connected shader: " + surface.Source.FullName, siSeverity.siInfo);
// To successfully retrieve output arguments, cast the generic object back to the correct class
DataSource oldsrc = (DataSource)oldone;
app.LogMessage("displaced shader: " + oldsrc.FullName, siSeverity.siInfo);
// Output:
// INFO : currently connected shader: MyCube.Material.MyPhong
// INFO : currently connected shader: MyCube.Material.Lambert
// INFO : displaced shader: Sources.Materials.DefaultLib.Material.MyPhong
オブジェクト モデルの汎用的なメソッドは、C# の汎用的なメソッドに変換されます。
// GetAttribute returns a string Variant in the OM which maps to the generic Object class in C#
Object obj = in_ctxt.GetAttribute("Button");
// To access the string value, a type cast must be performed to String
String str = (String)obj;
// Everything in C# is an Object type, so if a method returns a long you still need to typecast
long n = (long)in_ctxt.GetAttribute("LongAttribute");
オブジェクト モデルのほとんどのインタフェースでは、インスタンスのすべてのメソッドにキャストなしで直接アクセスできます。 ところが、ジオメトリ コレクション インタフェース(PolygonFaceCollection、NurbsSampleCollection など)の場合、メソッドを呼び出す前にインタフェースを明示的にキャストする必要があります。
PolygonFaceCollection polygons = (PolygonFaceCollection)subcomp.ComponentCollection; Array aNodeIndexArray = (Array)polygons.PolygonNodePolygonFaceIndexArray; // Type cast a gain to access FacetCollection.IndexArray FacetCollection polyFacets = (FacetCollection)polygons; Array aPolyIndexArray = (Array)polyFacets.IndexArray;
C# でプロパティを呼び出すための構文の動作は、JScript を使用した場合の動作とよく似ていますが、型宣言だけが大きく違います。
//JScript var params = oObject.Kinematics.Global.Parameters; // C# ParameterCollection params = oObject.Kinematics.Global.Parameters;
ところが、コレクションや、get- または set- アクセッサを使用しなければならない場合の特別な回避策の扱いに関して、構文的な違いもいくつかあります。
コレクション アイテムにアクセスするには、[]構文を使用します。
Parameter posy = oObject.Kinematics.Global.Parameters["posy"]; Parameter posx = oObject.Kinematics.Global.Parameters[0];
コレクションを反復する場合、最も簡単で信頼性の高いアプローチは、C# の foreach ループを使用することです。
ParameterCollection params = oObject.Kinematics.Global.Parameters;
foreach (Parameter p in params)
{
app.LogMessage( p.Name + " is a " + p.ValueType.ToString() );
}
オブジェクト モデルで定義される一部のプロパティは、取得と設定に関してさまざまなデータ タイプやクラスを使用します。 たとえば、XSIApplication.ActiveProject プロパティは、設定に関して String を取り、取得中に Project オブジェクトを返します。
// Won't compile Project p = xsi.ActiveProject; // Last line causes a compiler error Preferences pref = xsi.Preferences; ProjectItemCollection proj_itms = pref.Categories;
場合によっては、この問題を解決する代替のメソッドやプロパティが存在することもあります。たとえば、XSIApplication.ActiveProject2 は、Property オブジェクトを返し、設定する代替プロパティです。
// Alternate version of above snippet: Project p = xsi.ActiveProject2;
代替のメソッドやプロパティがない場合は、get_ や set_ をプロパティの前に付ける特別な構文を使用して、これをメソッドのように扱うことができます。
// Special syntax as a workaround ProjectItemCollection proj_itms = pref.get_Categories; pref.set_Categories( proj_itms );
この特別な構文を使用する場合、実際にはget-およびset-アクセッサメソッドを使用していることになります。これらのメソッドは、Visual C# ObjectBrowser でオブジェクトのメソッドを検索すると見つかります。
コマンドおよびスクリプト リファレンスの各プロパティ ページには「C# の構文」という特別なセクションがあります。ここには、アクセッサの取得と設定を行う基本的な C# の構文文字列が記載されています。データまたはクラスタイプが指定されているので、個々のアクセッサの使い方を理解することができます。たとえば、以下に示すのはPreferences.Categories ページのセクションです。
// get accessor Object Preferences.get_Categories(); // set accessor Preferences.set_Categories( [String pArrayVal] );
これを、Int32 値を設定して返す GridData.ColumnCount ページの C# の構文セクションと比較してください。
// get accessor Int32 GridData.ColumnCount(); // set accessor GridData.ColumnCount( [Int32 out_Columns] );
一部のオブジェクト モデル プロパティは、1 つまたは複数の入力引数を取ります。たとえば、Primitive.Geometry(特定のフレームでジオメトリの取得を可能にします)や FCurveKey.Constraint(FCurveKey で特定のコンストレイントがアクティブになっているかどうかをテストします)などです。これらのプロパティの多くには、対応する C# に適したメソッドがあります。リファレンス ドキュメントで、プロパティ名の前に「Get」を付け、後に「2」を付けて検索すると、これらが見つかります(たとえば、Primitive.GetGeometry2 や FCurveKey.GetConstraint2 など)。
対応する C# に適したメソッドがない場合は、代わりに get- または set- アクセッサを使用できます。
// Get the geometry at the current frame Geometry geo = obj.ActivePrimitive.get_Geometry((int)-1);
以下に、入力引数を取るオブジェクト モデル プロパティを示します。
|
|
|