How to Mirror Jig Multiple Entities

How to Mirror Jig Multiple Entities

Anonymous
Not applicable
746 Views
2 Replies
Message 1 of 3

How to Mirror Jig Multiple Entities

Anonymous
Not applicable

I am trying to pass an array of entities so that I can mirror them. At the moment, I can only do so with 1 entity at a time. Code below:

 

Imports System.Text
Imports System.Linq
Imports System.Xml
Imports System.Reflection
Imports System.ComponentModel
Imports System.Collections
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Media.Imaging
Imports System.Windows.Forms
Imports System.Drawing
Imports System.IO

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

Imports MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application
Imports MgdAcDocument = Autodesk.AutoCAD.ApplicationServices.Document
Imports AcWindowsNS = Autodesk.AutoCAD.Windows

Public Class MirrorJig
    Inherits EntityJig

#Region "Fields"
    Public mCurJigFactorIndex As Integer = 1

    Private m2ndPoint As New Point3d
    Private m1stPoint As Point3d
#End Region

#Region "Constructors"
    Public Sub New(ent As Entity, basePoint As Point3d)
        MyBase.New(ent)
        m1stPoint = basePoint.TransformBy(UCS)
    End Sub

#End Region

#Region "Properties"
    Private ReadOnly Property Editor() As Editor
        Get
            Return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor
        End Get
    End Property
    Private ReadOnly Property UCS() As Matrix3d
        Get
            Return Editor.CurrentUserCoordinateSystem
        End Get
    End Property
#End Region

#Region "Overrides"
    Private mLastMat As Matrix3d = Matrix3d.Identity
    Protected Overrides Function Update() As Boolean
        Dim mat As Matrix3d = Matrix3d.Mirroring(New Line3d(m1stPoint, m2ndPoint))
        Entity.TransformBy(mLastMat.Inverse().PostMultiplyBy(mat))
        mLastMat = mat

        Return True
    End Function
    Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
        Select Case mCurJigFactorIndex
            Case 1
                Dim prOptions1 As New JigPromptPointOptions(vbLf & "The second point of the mirror line: ")
                prOptions1.UserInputControls = UserInputControls.GovernedByUCSDetect Or UserInputControls.UseBasePointElevation Or UserInputControls.Accept3dCoordinates
                prOptions1.BasePoint = m1stPoint
                Dim prResult1 As PromptPointResult = prompts.AcquirePoint(prOptions1)
                If prResult1.Status = PromptStatus.Cancel Then
                    Return SamplerStatus.Cancel
                End If

                If prResult1.Value.Equals(m2ndPoint) Then
                    Return SamplerStatus.NoChange
                Else
                    m2ndPoint = prResult1.Value
                    Return SamplerStatus.OK
                End If
            Case Else
                Exit Select
        End Select

        Return SamplerStatus.OK
    End Function
#End Region

#Region "Methods to Call"
    Public Shared Function Jig(ent As Entity, basePt As Point3d) As Boolean
        Dim jigger As MirrorJig = Nothing
        Try
            jigger = New MirrorJig(ent, basePt)
            Dim pr As PromptResult
            Do
                pr = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.Drag(jigger)
                ' Add keyword handling code below

                If pr.Status = PromptStatus.Keyword Then
                Else
                    jigger.mCurJigFactorIndex += 1
                End If
            Loop While pr.Status <> PromptStatus.Cancel AndAlso pr.Status <> PromptStatus.[Error] AndAlso jigger.mCurJigFactorIndex <= 1

            If pr.Status = PromptStatus.Cancel OrElse pr.Status = PromptStatus.[Error] Then
                If jigger IsNot Nothing AndAlso jigger.Entity IsNot Nothing Then
                    jigger.Entity.Dispose()
                End If

                Return False
            Else
                Return True
            End If
        Catch
            If jigger IsNot Nothing AndAlso jigger.Entity IsNot Nothing Then
                jigger.Entity.Dispose()
            End If

            Return False
        End Try
    End Function
#End Region

#Region "Test Commands"

    <CommandMethod("TestMirrorJigger")> _
    Public Shared Sub TestMirrorJigger()
        Dim ed As Editor = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor
        Dim db As Database = HostApplicationServices.WorkingDatabase

        Try
            Dim selRes As PromptEntityResult = ed.GetEntity(vbLf & "Pick an entity:")
            Dim ptRes As PromptPointResult = ed.GetPoint(vbLf & "The first point of the mirror line: ")
            If selRes.Status = PromptStatus.OK AndAlso ptRes.Status = PromptStatus.OK Then
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim ent As Entity = TryCast(tr.GetObject(selRes.ObjectId, OpenMode.ForWrite), Entity)
                    If ent IsNot Nothing Then
                        Using tr1 As Transaction = db.TransactionManager.StartTransaction()
                            ent.Highlight()
                            tr1.Commit()
                        End Using

                        If MirrorJig.Jig(ent, ptRes.Value) Then
                            tr.Commit()
                        Else
                            tr.Abort()
                        End If
                    End If
                End Using
            End If
        Catch ex As System.Exception
            ed.WriteMessage(ex.ToString())
        End Try
    End Sub

#End Region
End Class

 

If I want to pass multiple entities I need to inherit DrawJig instead of EntityJig right? If that's the case, I would need to change quite a bit of stuff ... While also implementing WorldDraw...?

 

I'm kind of on the fence about this, not too sure how to approach the solution.Smiley Frustrated

0 Likes
Accepted solutions (1)
747 Views
2 Replies
Replies (2)
Message 2 of 3

Anonymous
Not applicable

Alright I've gotten a little further. All my entities get mirrored (or look like they are...)

 

But, I can't see the actual "Jigging" proccess... Here's what my MirrorJig.vb class looks like now:

 

Imports System.Text
Imports System.Linq
Imports System.Xml
Imports System.Reflection
Imports System.ComponentModel
Imports System.Collections
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Media.Imaging
Imports System.Windows.Forms
Imports System.Drawing
Imports System.IO

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

Imports MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application
Imports MgdAcDocument = Autodesk.AutoCAD.ApplicationServices.Document
Imports AcWindowsNS = Autodesk.AutoCAD.Windows

Public Class MirrorJig
    Inherits DrawJig

#Region "Fields"
    Public mCurJigFactorIndex As Integer = 1
    Private entities() As Entity
    Private m2ndPoint As New Point3d
    Private m1stPoint As Point3d
    Private Editor As Editor
    Private UCS As Matrix3d
#End Region

#Region "Constructors"
    Public Sub New(ent() As Entity, basePoint As Point3d)
        Me.entities = ent
        Editor = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor
        UCS = Editor.CurrentUserCoordinateSystem
        m1stPoint = basePoint.TransformBy(UCS)
    End Sub
#End Region

#Region "Overrides"
    Private mLastMat As Matrix3d = Matrix3d.Identity
    Protected Overrides Function WorldDraw(draw As Autodesk.AutoCAD.GraphicsInterface.WorldDraw) As Boolean
        Dim mat As Matrix3d = Matrix3d.Mirroring(New Line3d(m1stPoint, m2ndPoint))

        For Each e As Entity In entities
            e.TransformBy(mLastMat.Inverse().PostMultiplyBy(mat))
        Next
        mLastMat = mat

        Return True
    End Function
    Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
        Select Case mCurJigFactorIndex
            Case 1
                Dim prOptions1 As New JigPromptPointOptions(vbLf & "The second point of the mirror line: ")
                prOptions1.UserInputControls = UserInputControls.GovernedByUCSDetect Or UserInputControls.UseBasePointElevation Or UserInputControls.Accept3dCoordinates
                prOptions1.BasePoint = m1stPoint
                Dim prResult1 As PromptPointResult = prompts.AcquirePoint(prOptions1)
                If prResult1.Status = PromptStatus.Cancel Then
                    Return SamplerStatus.Cancel
                End If

                If prResult1.Value.Equals(m2ndPoint) Then
                    Return SamplerStatus.NoChange
                Else
                    m2ndPoint = prResult1.Value
                    Return SamplerStatus.OK
                End If
            Case Else
                Exit Select
        End Select

        Return SamplerStatus.OK
    End Function
#End Region

#Region "Methods to Call"
    Public Function Jig(ent() As Entity, basePt As Point3d) As Boolean
        Dim jigger As MirrorJig = Nothing
        Try
            jigger = New MirrorJig(ent, basePt)
            Dim pr As PromptResult
            Do
                pr = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.Drag(jigger)
                ' Add keyword handling code below

                If pr.Status = PromptStatus.Keyword Then
                Else
                    jigger.mCurJigFactorIndex += 1
                End If
            Loop While pr.Status <> PromptStatus.Cancel AndAlso pr.Status <> PromptStatus.[Error] AndAlso jigger.mCurJigFactorIndex <= 1

            If pr.Status = PromptStatus.Cancel OrElse pr.Status = PromptStatus.[Error] Then
                Return False
            Else
                Return True
            End If
        Catch
            Return False
        End Try
    End Function
#End Region
End Class

 

Is there something obvious I'm missing? I thought it would be in the "WorldDraw" function but I'm not sure what else to put there...

 

Any help is appreciated!

0 Likes
Message 3 of 3

Anonymous
Not applicable
Accepted solution

There I think I got it now:

 

Protected Overrides Function WorldDraw(draw As Autodesk.AutoCAD.GraphicsInterface.WorldDraw) As Boolean
    Dim mat As Matrix3d = Matrix3d.Mirroring(New Line3d(m1stPoint, m2ndPoint))
    Dim geo As Autodesk.AutoCAD.GraphicsInterface.WorldGeometry = draw.Geometry

    If geo IsNot Nothing Then
        geo.PushModelTransform(mat)

        For Each ent As Entity In entities
            geo.Draw(ent)
        Next

        geo.PopModelTransform()
    End If

    Return True
End Function

 success_mirror.png