読者です 読者をやめる 読者になる 読者になる

C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA

指定した平面から、穴の中心点を作成する4

こちらの続きです。
指定した平面から、穴の中心点を作成する3 - C#ATIA

ようやくメインの部分です。

//cs
namespace sample_Part_CenterPoint {
    using System;
    using System.Collections.Generic;
    using INFITF;//Catiaのライブラリ
    using MECMOD;//Catiaのライブラリ
    using System.Runtime.InteropServices;//COMオブジェクトを操作するために必要
    using HybridShapeTypeLib;

    class Program {
        static void Main(string[] args) {

            var CCP = new CreateCenterPoint();
            CCP.Execute();
        }
    }
    class CreateCenterPoint {
        public CreateCenterPoint() {
            var catia = (INFITF.Application)Marshal
                        .GetActiveObject("CATIA.Application");
            CatHelper.State = new CatiaContainer(catia);
        }

        public void Execute() {
            while (true) {
                var Result = CatHelper.SelectItem2<PlanarFace>
                    ("中心を作成する面を選択して下さい // [Esc]=キャンセル");
                if (Result == null) { return; }
                CreatePoint(Result);
            }
        }

        private void CreatePoint(PlanarFace Plan) {//①
            var DeleteList = new List<AnyObject>();

            //参照面データム化
            var Ext = CatHelper.NewExtract(Plan);
            DeleteList.Add(Ext);

            //境界抽出
            var Bou = CatHelper.NewBoundaryOfSurface(Ext.AsReference());
            DeleteList.Add(Bou);

            CatHelper.NewHybridBody("CenterPoint");
            CatHelper.State.HybridBody.AppendHybridShape(Bou);

            //分解
            CatHelper.State.Selection.Clear();
            CatHelper.State.Selection.Add(Bou);
            CatHelper.State.Selection.Search("Topology.CGMEdge,sel");

            foreach (var EdgeRef in CatHelper.State.Selection.AsEnumerable<Reference>()) {
                try {
                    var pnt = CatHelper.NewPointCenter(EdgeRef);
                    DeleteList.Add(pnt);
                    CatHelper.State.HybridBody.AppendHybridShape(pnt);
                    CatHelper.State.HybridBody.AppendHybridShape(
                        CatHelper.NewPointDatum(pnt.AsReference()));
                } catch { }
            }
            CatHelper.DeleteObject(DeleteList);
        }
    }
}

①:選択された面を受け取り、中心点作成の処理をしており、VBAと特に変わりは無いです。
 いかにも"手続き型"っぽい書き方になってしまっているのですが、他にどの様な
 書き方をすれば良いのかよくわかりません・・。(知りたい)

適当なモデルを作成し、VBAC#、それぞれのマクロ実行後の画像がこちら
f:id:kandennti:20150526081120p:plain
・・・結果が異なってますw 移植失敗ですね。
(C#では開いた円弧に対しても点が作成されています)
円弧が開いている?閉じている?は判断してないですし、マクロを作成している言語の
違いで挙動が変わるとも思えないので、恐らく他の部分でしょう。
細かい事を書けば、形状セット挿入とUpdateの順番やら、一時的な要素の削除タイミング
等が若干異なるので。


(以下、ボヤキです。)
毎回そうなのですが、CATIAの操作をCatHelperクラスに任せ、メインな処理部分では
要素の受け取り等だけにしたいと思って、この方法を行っているのですが
「CatHelper.State~」がやたらと出てきてしまい、可読性が異様に悪いです。

CatHelperクラスメソッドの呼び出しを行いやすくする為に、CatiaContainerクラス
(アクティブなCATIAの主要なオブジェクトを保持)のインスタンスをプロパティで保持しているのですが、
これが逆に悪いのでしょう。 と言っても2ヶ所からCatiaContainerクラスに対して
アクセスもしたくない・・・。 「どうせなら静的クラスに」と言う気持ちも
あるのですが "SelectElement4" の様に2つのドキュメントを保持したい場合に都合
悪いうえ、ドキュメントを切り替えたい場合に新たなインスタンスをササッと、CatHelperクラス
投げてしまえば楽だなぁと思ったり。 単にCatHelperクラスのメソッドの量がまだまだ
不足しているだけのような気もするのですが、現状でも単調な処理に対しても
大げさなソースコードの量になっているのも事実。 プロの方ならどの様にするのだろう・・・。