こちらの続きです。
Viewに基準線を入れる1 - C#ATIA
C#化しました。 相変わらず大げさなコードです。
//cs namespace Drw_Abs_Line { using System.Linq; using System.Windows.Forms; using System.Runtime.InteropServices;//COMオブジェクトを操作するために必要 using DRAFTINGITF;//Catiaのライブラリ using INFITF;//Catiaのライブラリ using MECMOD;//Catiaのライブラリ using System.Collections.Generic; static class Program { static void Main() { var catia = (INFITF.Application)Marshal .GetActiveObject("CATIA.Application"); var AbsLine = new Create_Abs_Line(catia); AbsLine.Execute(); } } class Create_Abs_Line { public Create_Abs_Line(INFITF.Application Catia) { CatHelper.State = new CatiaContainer(Catia); } public void Execute() { if (CatHelper.State.Views.Count < 3) { return; } var StartView = CatHelper.State.Views.ActiveView; foreach (var view in CatHelper.State.ViewsEnumerable .Where((v, index) => index > 1)) { if (!view.IsAbsLine()) { CatHelper.State.View = view; view.Activate(); CatHelper.Create_Line(-20d, 0d, 20d, 0d); CatHelper.Create_Line(0d, -20d, 0d, 20d); } } StartView.Activate(); } } class CatiaContainer { private INFITF.Application catia; public CatiaContainer(INFITF.Application cat) { Catia = cat; Setting(); } ~CatiaContainer() { if (catia != null) { Marshal.ReleaseComObject(catia); } } public void Setting() { DrawDoc = catia.ActiveDocument as DrawingDocument; Views = DrawDoc.Sheets.ActiveSheet.Views; Selection = DrawDoc.Selection; } public INFITF.Application Catia { get { return catia; } private set { catia = value; } } public DrawingDocument DrawDoc { get; private set; } public DrawingViews Views { get; private set; } public Selection Selection { get; private set; } public IEnumerable<DrawingView> ViewsEnumerable { get { return Enumerable.Range(1, Views.Count) .Select(i => Views.Item(i)); } } public DrawingView View { get; set; } public Factory2D Fac2D { get { return View.Factory2D; } } } static class CatHelper { public static CatiaContainer State { get; set; } public static void Create_Line(double x1, double y1, double x2, double y2) { var L2D = State.Fac2D.CreateLine(x1, y1, x2, y2); State.Selection.Clear(); State.Selection.Add(L2D); State.Selection.VisProperties.SetRealLineType(4, 0); State.Selection.VisProperties.SetRealWidth(1, 0); State.Selection.Clear(); L2D.set_Name("Abs_Line"); } public static bool IsAbsLine(this DrawingView vi) { foreach (GeometricElement Geo in vi.GeometricElements) {//① if (Geo.get_Name() == "Abs_Line") { return true; } } return false; } } }
Create_Abs_LineクラスのViewsの回り方と、CatiaContainerクラスは
こちらをほぼ流用。
Viewのロック・アンロック2 - C#ATIA
CatHelperクラスはVBAのCreate_Line・IsAbsLineメソッドを積んだのみ
となっています。
①:LinqのAnyメソッドを使用すると1行で書けるのですが、
素直にforeachにしました。Linqだとこんな感じです。
//cs public static bool IsAbsLine(this DrawingView vi) { return Enumerable.Range(1, vi.GeometricElements.Count) .Select(Geo => vi.GeometricElements.Item(Geo)) .Any(Geo => Geo.get_Name() == "Abs_Line"); }
こっちの方がカッコいいかも。
「Range」と「Select」はCOMのコレクションでLinqを使用するための準備なので、
実質「Any」だけですね。 そう考えると、こちらの最後の方にも記載した
Viewのロック・アンロック2 - C#ATIA
ToEnumerable<T>のようなジェネリックメソッドが欲しいところ。
オブジェクト名でイチイチ判断するのも面倒なため、
リフレクションで「Count」や「Add」の有無で判断しdynamic型で・・・
とも思ったのですが、Selectionクラスだけが他のコレクションと
挙動が違うので・・・。それだけ別処理されるのもアリかな?