Results 1 to 10 of 10

Thread: Rotate block on insert (while being able to see what rotated block would look like)

  1. #1
    Member
    Join Date
    2011-10
    Posts
    39


    Default Rotate block on insert (while being able to see what rotated block would look like)

    Hi, I want to be able to insert a block using vb.net and rotate that block during insertion, while being able to see what the rotation would look like.

    The old Macro we used to do this was this *^C^C(command "layer" "m" "CSVGSYM" "ltype" "continuous" "" "color" "150" "" "")(command "insert" "221" "S" msf (getpoint))

    This would insert the block on the layer and allow the user to rotate it after picking the insertion point, showing the user what the rotation would look like.

    If I use this:
    acedPostCommand("(command ""layer"" ""m"" ""CSVGSYM"" ""ltype"" ""continuous"" """" ""color"" ""150"" """" """") ")
    acedPostCommand("(command ""insert"" ""221"" ""S"" msf (getpoint))")

    It works properly but I cannot put it in a loop as it does not wait for a user response before looping again.

    If I put it in a loop like this the problem is that I don't get to see what the rotated image would look while selecting the rotation angle.

    Code:
          
    insertRotatedBlock("X:\\Blocks\\221.dwg", "CSVGSYM", 150, "continuous")
          
    Private Sub insertRotatedBlock(location As String, layer As String, color As String, linetype As String)
            ThisDrawing = CType(Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument), Autodesk.AutoCAD.Interop.AcadDocument)
            Dim tempBlock As AcadBlockReference
            Dim userPoint As Object
    
            Do
                Try
                    userPoint = ThisDrawing.Utility.GetPoint(, "Specify insertion point:")
                    checkNewLayer(layer, color)
                    tempBlock = ThisDrawing.ModelSpace.InsertBlock(userPoint, location, (drawingSetting.getScale() / 1000), (drawingSetting.getScale() / 1000), (drawingSetting.getScale() / 1000), ThisDrawing.Utility.GetAngle(userPoint, "Select Rotation Angle: "))
                    tempBlock.Layer = layer
                    tempBlock.Linetype = linetype
                Catch ex As System.Runtime.InteropServices.ExternalException
                    Exit Do
                Catch exs As Exception
                    Exit Do
                End Try
            Loop
        End Sub
    Any help would be appreciated, thanks

  2. #2
    Programming Moderator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,125


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    I'm confused... I do not understand why such a simple macro is being redone in VB.NET when a far simpler LISP would suffice, and still be callable via your existing Toolbar/Menu macro?

    Code:
    (vl-load-com)
    
    (defun c:FOO (/ *error* layerName oldClayer)
    
      (defun *error* (msg)
        (and oldClayer (setvar 'clayer oldClayer))
        (cond ((not msg))                                                   ; Normal exit
              ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
              ((princ msg))                                                 ; Fatal error, display it
        )
        (princ)
      )
    
      ;; layer check
      (if (not (tblsearch "layer" (setq layerName "CSVGSYM")))
        (vla-put-color
          (vla-add (vla-get-layers
                     (vla-get-activedocument (vlax-get-acad-object))
                   )
                   layerName
          )
          150
        )
      )
    
      ;; set the desired layer
      (setq oldClayer (getvar 'clayer))
      (setvar 'clayer layerName)
    
      ;; loop block insertion
      (while (vl-cmdf "._-insert" "221" pause 1.0 1.0 pause))
    
      ;; exit
      (*error* nil)
    )
    ** Edit - You might also consider the acet-ss-drag-rotate function, if you do not care for my implementation above.


    Further perplexing, and please forgive my saying so as I know nothing of your proficiency at .NET development, but I really do not understand why if you're going to step up into the .NET API, you'd still be performing simple tasks such as adding a Layer via acedPostCommand, SendStringToExecute, or the like... Instead, just Create and Name Layers.

    Cheers
    "Potential has a shelf life." - Margaret Atwood
    AutoCAD, and Civil 3D Certified Professional | Autodesk Authorized Developer
    Sincpac C3D ~ Autodesk Exchange Apps

  3. #3
    AUGI Addict fixo's Avatar
    Join Date
    2005-05
    Location
    Pietari, Venäjä
    Posts
    1,269


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    Another way is to use acedCmd instead as this is
    well explained in this article:
    http://adndevblog.typepad.com/autoca...ing-c-net.html
    "The whole problem with the world is that fools and fanatics are always
    so certain of themselves, and wiser people so full of doubts."
    Bertrand Russell

  4. #4
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    201


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    Hi,

    If you want/need to do it in plain .NET you'll have to use Jigs (if you don't, you'd rather keep on using command macros and/or AutoLISP instead of trying to script with .NET and the COM interop).

    Here's a little example using to classes derived from EntityJig. The first one is used to insert the block, the second to rotate it.

    VB
    Code:
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports Autodesk.AutoCAD.EditorInput
    Imports Autodesk.AutoCAD.Geometry
    Imports Autodesk.AutoCAD.Runtime
    
    <Assembly: CommandClass(GetType(InsertRotateJigSample.CommandMethods))> 
    
    Namespace InsertRotateJigSample
    
        Public Class CommandMethods
    
            <CommandMethod("Test", CommandFlags.Modal)> _
            Public Sub Test()
                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim db As Database = doc.Database
                Dim ed As Editor = doc.Editor
    
                Dim pr As PromptResult = ed.GetString(vbLf & "Enter the block name: ")
                If pr.Status <> PromptStatus.OK Then
                    Return
                End If
                Dim blkName As String = pr.StringResult
    
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim bt As BlockTable = _
                        DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                    If Not bt.Has(blkName) Then
                        ed.WriteMessage(vbLf & "Block '{0}' not found.", blkName)
                        Return
                    End If
                    Using br As New BlockReference(Point3d.Origin, bt(blkName))
                        br.TransformBy(ed.CurrentUserCoordinateSystem)
    
                        ' Using InsertBlockJig class to insert the block
                        Dim insertJig As New InsertBlockJig(br)
                        pr = ed.Drag(insertJig)
                        If pr.Status <> PromptStatus.OK Then
                            Return
                        End If
    
                        ' Using RotateBlockJig class to rotate the block
                        Dim rotateJig As New RotateBlockJig(br)
                        pr = ed.Drag(rotateJig)
                        If pr.Status <> PromptStatus.OK Then
                            Return
                        End If
                        rotateJig.UpdateRotation()
    
                        Dim btr As BlockTableRecord = _
                            DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                        btr.AppendEntity(br)
                        tr.AddNewlyCreatedDBObject(br, True)
                    End Using
                    tr.Commit()
                End Using
            End Sub
    
        End Class
    
        Class InsertBlockJig
            Inherits EntityJig
    
            ' Protected fields
            Protected position As Point3d
            Protected br As BlockReference
    
            ' Constructor (fields initialization)
            Public Sub New(br As BlockReference)
                MyBase.New(br)
                Me.br = br
                Me.position = br.Position
            End Sub
    
            ' Prompts the user to specify the insertion point (EntityJig implementation)
            Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
                Dim msg As String = vbLf & "Specify the insertion point: "
                Dim jppo As New JigPromptPointOptions(msg)
                jppo.UserInputControls = (UserInputControls.Accept3dCoordinates Or _
                                          UserInputControls.NullResponseAccepted)
                Dim ppr As PromptPointResult = prompts.AcquirePoint(jppo)
                If Me.position.DistanceTo(ppr.Value) < Tolerance.[Global].EqualPoint Then
                    Return SamplerStatus.NoChange
                Else
                    Me.position = ppr.Value
                End If
                Return SamplerStatus.OK
            End Function
    
            ' Updates the bloc position (EntityJig implementation) 
            Protected Overrides Function Update() As Boolean
                Me.br.Position = Me.position
                Return True
            End Function
        End Class
    
        Class RotateBlockJig
            Inherits EntityJig
    
            ' Private fields
            Protected br As BlockReference
            Protected rot As Double, ucsRot As Double
    
            ' Constructor
            Public Sub New(br As BlockReference)
                MyBase.New(br)
                Me.br = br
                Me.ucsRot = br.Rotation
            End Sub
    
            ' Prompts the user to specify the rotation (EntityJig implementation)
            Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
                Dim jpao As New JigPromptAngleOptions(vbLf & "Specify the rotation: ")
                jpao.DefaultValue = 0.0
                jpao.UseBasePoint = True
                jpao.BasePoint = Me.br.Position
                jpao.Cursor = CursorType.RubberBand
                jpao.UserInputControls = (UserInputControls.Accept3dCoordinates Or _
                                          UserInputControls.UseBasePointElevation Or _
                                          UserInputControls.NullResponseAccepted)
                Dim pdr As PromptDoubleResult = prompts.AcquireAngle(jpao)
    
                If Me.rot = pdr.Value Then
                    Return SamplerStatus.NoChange
                Else
                    Me.rot = pdr.Value
                    Return SamplerStatus.OK
                End If
            End Function
    
            ' Updates the bloc rotation (EntityJig implementation) 
            Protected Overrides Function Update() As Boolean
                UpdateRotation()
                Return True
            End Function
    
            ' Updates the bloc rotation (mandatory for the 'default' option)
            ' This method is called from the method where the jig is created
            Friend Sub UpdateRotation()
                Me.br.Rotation = Me.rot + Me.ucsRot
            End Sub
        End Class
    
    End Namespace

  5. #5
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    201


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    If you realy want/need scripting with .NET, you can use the following Editor extension method shared by Tony Tanzillo.
    This method wraps the undocumented RunCommand() method which works the same as the AutoLISP 'command' function and accepts managed types as arguments.

    C#
    Code:
    using System;
    using System.Reflection;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.EditorInput;
    
    namespace InsertRotateJigSample
    {
        // From Tony Tanzillo (using reflection)
        // http://www.theswamp.org/index.php?topic=43113.msg483306#msg483306
        public static class EditorExtensions
        {
            public static PromptStatus Command(this Editor ed, params object[] args)
            {
                if (Application.DocumentManager.IsApplicationContext)
                    throw new InvalidOperationException("Invalid execution context for Command()");
                if (ed.Document != Application.DocumentManager.MdiActiveDocument)
                    throw new InvalidOperationException("Document is not active");
                return (PromptStatus)runCommand.Invoke(ed, new object[] { args });
            }
    
            static MethodInfo runCommand = typeof(Editor).GetMethod(
                "RunCommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        }
    }
    VB
    Code:
    Imports System.Reflection
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.EditorInput
    
    Namespace InsertRotateJigSample
    
        ' From Tony Tanzillo (using reflection)
        ' http://www.theswamp.org/index.php?topic=43113.msg483306#msg483306
        Module EditorExtensions
    
            <System.Runtime.CompilerServices.Extension> _
            Public Function Command(ed As Editor, ParamArray args As Object()) As PromptStatus
                If Application.DocumentManager.IsApplicationContext Then
                    Throw New InvalidOperationException("Invalid execution context for Command()")
                End If
                If ed.Document <> Application.DocumentManager.MdiActiveDocument Then
                    Throw New InvalidOperationException("Document is not active")
                End If
                Return DirectCast(runCommand.Invoke(ed, New Object() {args}), PromptStatus)
            End Function
    
            Dim runCommand As MethodInfo = GetType(Editor).GetMethod( _
                "RunCommand", BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.[Public])
    
        End Module
    
    End Namespace
    Adding this module to your project, you'd be able to use the Editor.Command() method as the AutoLISP 'command' function:

    Code:
    Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
    ed.Command("_insert", "221", "\", 1.0, 1.0, "\")

  6. #6
    Programming Moderator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,125


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    Gile -

    You and Tony never fail to amaze, and are both incredibly kind to continue to offer this community all that you do.

    Cheers
    "Potential has a shelf life." - Margaret Atwood
    AutoCAD, and Civil 3D Certified Professional | Autodesk Authorized Developer
    Sincpac C3D ~ Autodesk Exchange Apps

  7. #7
    AUGI Addict fixo's Avatar
    Join Date
    2005-05
    Location
    Pietari, Venäjä
    Posts
    1,269


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    Quote Originally Posted by BlackBox View Post
    Gile -

    You and Tony never fail to amaze, and are both incredibly kind to continue to offer this community all that you do.

    Cheers
    Subscribe to your opinion,
    Regards
    "The whole problem with the world is that fools and fanatics are always
    so certain of themselves, and wiser people so full of doubts."
    Bertrand Russell

  8. #8
    100 Club Brian C's Avatar
    Join Date
    2008-08
    Location
    Vancouver, BC
    Posts
    105


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    Blackbox - you vla code works well - that block insert is very useful for me

    Thank you for sharing it.
    Brian C
    *********
    "The difference is my flaws are personal. Yours are professional." [Col. Tigh, BSG 2004]

  9. #9
    Programming Moderator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,125


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    Quote Originally Posted by Brian C View Post
    Blackbox - you vla code works well - that block insert is very useful for me

    Thank you for sharing it.
    You're welcome, Brian - I'm always happy to help.
    "Potential has a shelf life." - Margaret Atwood
    AutoCAD, and Civil 3D Certified Professional | Autodesk Authorized Developer
    Sincpac C3D ~ Autodesk Exchange Apps

  10. #10
    Woo! Hoo! my 1st post
    Join Date
    2015-12
    Posts
    1


    Default Re: Rotate block on insert (while being able to see what rotated block would look like)

    Quote Originally Posted by fixo View Post
    Subscribe to your opinion,
    Regards
    I too second the motion.

    much appreciated.

    I hope to contribute to the community as well.

    how? i have no idea. but i'll find a way

Similar Threads

  1. Replies: 3
    Last Post: 2014-03-26, 08:19 PM
  2. Insert a Tool Palette Block While Editing a Block or Xref.
    By Wish List System in forum AutoCAD Wish List
    Replies: 1
    Last Post: 2013-10-07, 04:53 PM
  3. Replies: 5
    Last Post: 2012-12-10, 07:10 PM
  4. Replies: 19
    Last Post: 2006-03-14, 05:06 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •