お知らせ

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

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

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

2010年4月16日金曜日

.NET の勉強 「オブジェクトの削除、コピー、移動」(AutoCAD 2011)

先週から、金曜日は .NET の勉強をしようかということにしたので、今日はその続きです。

前回は、オブジェクトを作成するプログラムの勉強をしたので、今回は、オブジェクトの削除やコピーや移動などを行うサンプルを探してみました。


そこで、こんなサンプルを見つけて、とりあえず実行してみました。

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry

<CommandMethod("EraseObject")> _
Public Sub EraseObject()

    '' Get the current document and database
    Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
    Dim acCurDb As Database = acDoc.Database

    '' Start a transaction
    Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

        '' Open the Block table for read
        Dim acBlkTbl As BlockTable
        acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)

        '' Open the Block table record Model space for write
        Dim acBlkTblRec As BlockTableRecord
        acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), _
                                                            OpenMode.ForWrite)

        '' Create a lightweight polyline
        Dim acPoly As Polyline = New Polyline()
        acPoly.SetDatabaseDefaults()
        acPoly.AddVertexAt(0, New Point2d(2, 4), 0, 0, 0)
        acPoly.AddVertexAt(1, New Point2d(4, 2), 0, 0, 0)
        acPoly.AddVertexAt(2, New Point2d(6, 4), 0, 0, 0)

        '' Add the new object to the block table record and the transaction
        acBlkTblRec.AppendEntity(acPoly)
        acTrans.AddNewlyCreatedDBObject(acPoly, True)

        '' Update the display and display an alert message
        acDoc.Editor.Regen()
        Application.ShowAlertDialog("Erase the newly added polyline.")

        '' Erase the polyline from the drawing
        acPoly.Erase(True)

        '' Save the new object to the database
        acTrans.Commit()

    End Using
End Sub



このプログラムは、ポリラインをひとつ作成して、それを削除するようです。


ポリラインの作成に関しては、前回の線分、円、MTEXT の作成と同じように、オブジェクトを宣言したあと、それぞれのプロパティを指定しているようです。(「'' Create a lightweight polyline」 以下の 5 行 および 「'' Add the new object to the block table record and the transaction」 以下の 2 行。)


で、削除しているのは、acPoly.Erase(True) ですね。
意外と簡単ですね。


他のコピーを行うサンプルを見てみたところ、Clone っていうのでコピーするみたいです。
なので、acPoly.Erase(True) の代わりに以下を記述したところ、無事コピーされました。

Dim acPolyClone As Polyline = acPoly.Clone()

acBlkTblRec.AppendEntity(acPolyClone)
acTrans.AddNewlyCreatedDBObject(acPolyClone, True)



ただし、まったく同じ場所にコピーされるので、もとのポリラインと重なっています。
他の場所にコピーしたいときは、どうするんだろう???移動と組み合わせるのかな???


そこで、移動を行うサンプルを見てみたところ、移動する場所を示すマトリックスを作ってから移動するようです。
そこで、以下のように記述を変更して実行してみたところ、無事に コピー+移動 を行うことができました。(基点が 0,0 で、目的点が 2,0)

Dim acPolyClone As Polyline = acPoly.Clone()

Dim acPt3d As Point3d = New Point3d(0, 0, 0)
Dim acVec3d As Vector3d = acPt3d.GetVectorTo(New Point3d(2, 0, 0))
acPolyClone.TransformBy(Matrix3d.Displacement(acVec3d))

acBlkTblRec.AppendEntity(acPolyClone)
acTrans.AddNewlyCreatedDBObject(acPolyClone, True)



ここで、ちょっと疑問に思ったのが、この例ではプログラムで作成したオブジェクトを移動しましたが、元からあるオブジェクトを選択して、移動したいときはどうなるんでしょう???
AutoLISP だと、entsel とか使うやつです。


サンプルを探してみたところ、きっと GetSelection ってやつですね。
そこで、前述の代わりに、以下を記述してみたところ、オブジェクトの選択を求められて、それを移動することができました。

※ このとき、「Imports Autodesk.AutoCAD.EditorInput」 も追加しました。


'' Request for objects to be selected in the drawing area
Dim acSSPrompt As PromptSelectionResult = acDoc.Editor.GetSelection()

'' If the prompt status is OK, objects were selected
If acSSPrompt.Status = PromptStatus.OK Then
    Dim acSSet As SelectionSet = acSSPrompt.Value

    '' Step through the objects in the selection set        
    For Each acSSObj As SelectedObject In acSSet

        '' Check to make sure a valid SelectedObject object was returned            
        If Not IsDBNull(acSSObj) Then
            '' Open the selected object for write                
            Dim acEnt As Entity = acTrans.GetObject(acSSObj.ObjectId, OpenMode.ForWrite)
            If Not IsDBNull(acEnt) Then
                Dim acClone As Entity = acEnt.Clone()
                Dim acPt3d As Point3d = New Point3d(0, 0, 0)
                Dim acVec3d As Vector3d = acPt3d.GetVectorTo(New Point3d(2, 0, 0))

                acClone.TransformBy(Matrix3d.Displacement(acVec3d))
                acBlkTblRec.AppendEntity(acClone)
                acTrans.AddNewlyCreatedDBObject(acClone, True)
            End If
        End If
    Next
End If



まだちゃんと理解できたわけではありませんが、とりあえず、オブジェクトの作成、削除、コピー、移動を実行するプログラムは作れるようになりました。


今後も、どんどん進んでいこうと思います。
きっとそのうち、自然と理解できるるようになるだろうと期待してます。

0 件のコメント:

コメントを投稿