お知らせ

--------------------------------------------------

プログラム作成/コンサルティングの申し込みはこちら

--------------------------------------------------

2010年11月6日土曜日

.NET(サンプル プログラム) - 「ハッチングの境界をまとめて選択」(AutoCAD 2011)

先日いただいたアンケートの中に、『ハッチングの境界だけをまとめて選択したい』 というものがありました。

普通のコマンドでは、そのようなことはできないと思うので、.NET でコマンドをひとつ作ってみました。

DLL ファイル(AVDO_SelectBoundaries.dll)は こちら です。

使い方は、こんな感じです。

  1. NETLOAD コマンドを実行して、AVDO_SelectBoundaries.dll をロードします。
  2. AVDO_SelectBoundaries コマンドを実行します。
  3. ハッチングの境界を探す対象の図形を選択します。(すべての図形を対象とするときは、ALL と入力します。)
  4. Enter キーを押して、選択を完了します。

すると、ハッチングの境界だけが選択された状態になります。

※ PICKFIRST にも対応しているので、図形を選択したあとに AVDO_SelectBoundaries コマンドを実行しても OK です。
※ 自動調整ハッチングの境界を探しているので、自動調整でないハッチングの境界は対象外です。

動画も作りましたので、見てみてください。


ハッチングの境界を見つける方法は比較的簡単に分かったんですが、コマンド終了後に境界が選択された状態にしておく方法がなかなか見つけられなくて苦労しました。

SetImpliedSelection っていうのでできるっていうのをググッて見つけたんですが、arxmgd.chm にはそれが載ってないんですよね。それなのに、みんななんで知ってるんでしょうね。

また、SetImpliedSelection がうまく動かなかったときに、Twitter で takamoda さんや u2suzuki さんに助言いただき助かりました。どうもありがとうございました。

ということで、コードはこんな感じです。

'-----------------------------------------------
' CommandFlags.Redraw の記述がないと、コマンド終了後に図形が選択された状態にならないので、必ず付けること!!
<CommandMethod("AVDO_SelectBoundaries", "AVDO_SelectBoundaries", CommandFlags.Modal + CommandFlags.Redraw)> _
Public Sub AVDO_SelectBoundaries()
    Dim doc As Document = Application.DocumentManager.MdiActiveDocument
    Dim db As Database = doc.Database
    Dim ed As Editor = doc.Editor

    ' コマンド実行時に選択されている図形設定
    Dim result As PromptSelectionResult = ed.SelectImplied()

    ' コマンド実行時に、図形が選択されていないときは、図形を選択するよう要求
    If (result.Status <> PromptStatus.OK) Then
        result = ed.GetSelection()
    End If

    ' 図形が選択されているときは以下を実行する
    If (result.Status = PromptStatus.OK) Then
        Using trans As Transaction = db.TransactionManager.StartTransaction
            Try
                Dim bt As BlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead)
                Dim btRec As BlockTableRecord

                Dim cSpace As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForRead)
                If cSpace.Name = "*Model_Space" Then
                    btRec = trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
                Else
                    btRec = trans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite)
                End If

                'ハッチング境界用のコレクション
                Dim bObjIdColl As New ObjectIdCollection


                For Each selObj As SelectedObject In result.Value
                    Dim ent As Entity = trans.GetObject(selObj.ObjectId, OpenMode.ForRead)
                    Dim objIdColl As ObjectIdCollection = ent.GetPersistentReactorIds
                    For Each objId As ObjectId In objIdColl
                        Dim dbObj As DBObject = trans.GetObject(objId, OpenMode.ForRead)

                        'もし、リアクターのタイプが Hatch だったら、コレクションに追加
                        If TypeOf dbObj Is Hatch Then
                            bObjIdColl.Add(selObj.ObjectId)
                        End If
                    Next
                Next

                ' pickfirst set をクリア
                ed.SetImpliedSelection(New ObjectId(-1) {})

                ' コレクションを配列にダンプ
                Dim ids As ObjectId() = New ObjectId(bObjIdColl.Count - 1) {}
                bObjIdColl.CopyTo(ids, 0)

                ' pickfirst set を設定
                ed.SetImpliedSelection(ids)

            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                Application.ShowAlertDialog(ex.Message)

            End Try
        End Using
    End If
End Sub
'-----------------------------------------------

0 件のコメント:

コメントを投稿