こちらの続きです。kantoku.hatenablog.com
//C# namespace cattest1 { using System.Collections.Generic; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices;//COMオブジェクトを操作するために必要 using INFITF;//Catiaのライブラリ using MECMOD;//Catiaのライブラリ using HybridShapeTypeLib;//Catiaのライブラリ ① class Program { static void Main() { var catia = (INFITF.Application)Marshal.GetActiveObject("CATIA.Application"); var test = new SpeedTest_CS(catia); Stopwatch sw = new Stopwatch(); sw.Start(); test.StartTest(); sw.Stop(); MessageBox.Show(string.Format("{0}秒", sw.Elapsed)); } } class SpeedTest_CS { INFITF.Application catia; public SpeedTest_CS(INFITF.Application Catia) { this.catia = Catia; } public void StartTest() { var PartDoc = catia.ActiveDocument as PartDocument;//② var oPart = PartDoc.Part as Part;//② var oHybShpFact = oPart.HybridShapeFactory as HybridShapeFactory; var colMyObj1 = new List<HybridShapePointExplicit>(); //Add Body HybridBody oHybBdy = oPart.HybridBodies.Add(); //Create RefPoint object[] oPt = { 0d, 0d, 0d };//CATSafeArrayVariantはobject配列 HybridShapePointCoord oHybShpPt = oHybShpFact.AddNewPointCoord((double)oPt[0], (double)oPt[1], (double)oPt[2]); oHybBdy.AppendHybridShape(oHybShpPt); oPart.UpdateObject(oHybShpPt); //Create DetumPoints HybridShapePointExplicit oHybShpPtExp = null; for (int i = 0; i < 500; i++) { oPt[0] = (double)oPt[0] + 10d; oHybShpPt.SetCoordinates(oPt); oPart.UpdateObject((AnyObject)oHybShpPt); oHybShpPtExp = oHybShpFact.AddNewPointDatum(oPart.CreateReferenceFromObject(oHybShpPt));//③ colMyObj1.Add(oHybShpPtExp); } //Append DetumPoints foreach (var oMyobj in colMyObj1) { oHybBdy.AppendHybridShape(oMyobj); } oHybShpFact.DeleteObjectForDatum(oPart.CreateReferenceFromObject(oHybShpPt));//③ oPart.Update(); colMyObj1 = null; } } }
まず①の部分ですが、HybridShapeFactoryを利用するためのライブラリです。
「CATIA V5 CATGSMIDLItf Object Library」が該当するのですが、名称を
省略されすぎて正直気が付かないです。毎度苦労します。
(恐らく大文字部分は省略されている部分です)
②の部分は、VBAの
Set oPart = CATIA.ActiveDocument.Part
に該当する部分ですが、C#の場合は「プロパティ.プロパティ(オブジェクト)」
の形ではエラーとなってしまう場合が多いです。
プロパティ取得後、一度キャストを行い再度プロパティの取得となり
VBAに比べコードが長くなってしまいます。
良い方法をご存知の方がいらっしゃいましたら教えてください。
③の部分は点のデータム化と最初に作った点の削除ですが、VBAでは
Set oHybShpPtExp = oHybShpFact.AddNewPointDatum(oHybShpPt) Call oHybShpFact.DeleteObjectForDatum(oHybShpPt)
と直接オブジェクトをパラメータとしていますが、同様の記述をC#で
行うとエラーとなってしまいました。
オートメーションマニュアルを見ると、両方とも「Reference iObject」
となっており、Reference化しています。
(VBAの型管理の甘さが、良い方向に働いているんですね・・・)
実行した結果です。
1回目:3.342秒
2回目:4.50秒
3回目:3.966秒
VBAより遅いですね。幾つか原因は推測できます。
一つはアウトプロセスとなってしまっている事です。 VBAでも
アウトプロセスは遅いです。
又、COMオブジェクトに対し"System.Runtime.InteropServices"
経由で処理される部分の若干あるのではないのかと思います。
但し、これを使用しないで行う方法を僕は知りません。
(動的にオブジェクトを取得する方法では、結果的にリフレクションで
行うことになると思いますが、リフレクションも遅いはずです)
後は、パッと見てもキャストが多いです。キャストは遅いんです。
それ以上にこのソースを見て「VBAで良いんじゃないの?」
と感じませんか? C#らしさが全く無いんですよ。
海外のサイトに少しはソースが落ちているのですが、全体的に
このようなコードばかりなんです。 もっとC#らしさを出したいと思いませんか?