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
    Login to Give a bone
    0

    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
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    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
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  3. #3
    AUGI Addict fixo's Avatar
    Join Date
    2005-05
    Location
    Pietari, Venäjä
    Posts
    1,269
    Login to Give a bone
    0

    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

  4. #4
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    201
    Login to Give a bone
    0

    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
    Login to Give a bone
    0

    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
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    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
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  7. #7
    AUGI Addict fixo's Avatar
    Join Date
    2005-05
    Location
    Pietari, Venäjä
    Posts
    1,269
    Login to Give a bone
    0

    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

  8. #8
    100 Club
    Join Date
    2008-08
    Location
    Vancouver, BC
    Posts
    105
    Login to Give a bone
    0

    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.

  9. #9
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    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.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  10. #10
    Woo! Hoo! my 1st post
    Join Date
    2015-12
    Posts
    1
    Login to Give a bone
    0

    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
  •