C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

スピードテスト2

こちらの続きです。kantoku.hatenablog.com

なるべくVBAと同じになるようにC#したソースコードです。

//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#らしさを出したいと思いませんか?