Jump to content

Measure-like Command


wannabe

Recommended Posts

Good morning,

 

I'd like to know if anyone has a way of copying a point or block along a line/pline the way the measure command does; but only one instance of a point or block; and rotating the point/block to follow the curvature of the line/pline in the same way the measure command does.

 

Cheers

Link to comment
Share on other sites

  • Replies 53
  • Created
  • Last Reply

Top Posters In This Topic

  • wannabe

    17

  • SEANT

    14

  • David Bethel

    6

  • ASMI

    5

I design balustrades and most of the time I have to put posts at certain ctrs around a radius or arc. I have a spreadsheet that helps me with this.

 

Im pretty sure LeeMac will have a lisp for what you require.

but I hope this can help. (someway)

Drawing Aids.zip

Link to comment
Share on other sites

Sounds like the array command would be ideal for you?

 

My application is about copying a block along a path e.g a road, railway etc. where the path has many intricate curves and 3D movements. All I want to do is copy a block X amount of distance along the line in plan view, ignoring Z values.

 

Cheers.

Link to comment
Share on other sites

Time was limited so there is ridiculously minimal testing and error checking, but:

 

        [CommandMethod("rdap")]
       static public void RefDistAlongPath()
       {
           Database db = HostApplicationServices.WorkingDatabase;
           Editor ed = Acad.DocumentManager.MdiActiveDocument.Editor;
           using (Transaction trans = db.TransactionManager.StartTransaction())
           {
               // Put your command code here
               PromptEntityOptions peo = new PromptEntityOptions("Select target curve: ");
               peo.SetRejectMessage("\nPlease only select a curve entity!");
               peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Curve), false);
               PromptEntityResult per = ed.GetEntity(peo);
               if (per.Status != PromptStatus.OK) return;
               ObjectId oid = per.ObjectId;
               Curve crv = (Curve)trans.GetObject(oid, OpenMode.ForRead, false);
               Plane pl = new Plane(ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Origin, ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis);
               Curve projCrv = crv.GetOrthoProjectedCurve(pl);
               PromptStringOptions pso = new PromptStringOptions("Enter name of block to create reference: ");
               PromptResult pr = ed.GetString(pso);
               String blkName = pr.StringResult;
               BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);     
               if (!bt.Has(blkName)) 
               { 
                   ed.WriteMessage ("Current Database does not contain a block of that name!");
                   return;
               }
               BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[blkName], OpenMode.ForRead);
               PromptDistanceOptions pdo = new PromptDistanceOptions("Indicate distance along path: ");
               pdo.AllowArbitraryInput = false;
               PromptDoubleResult pdr = ed.GetDistance(pdo);
               if (pdr.Status != PromptStatus.OK) return;
               Point3d p3d = projCrv.GetPointAtDist(pdr.Value);
               Vector3d v3d = projCrv.GetFirstDerivative(p3d);
               Double ang = Math.Atan(v3d.Y / v3d.X);
               BlockTableRecord currSpace = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
               BlockReference insert = new BlockReference(p3d, btr.ObjectId);
               insert.Rotation = ang;
               currSpace.AppendEntity(insert);
               insert.SetDatabaseDefaults();
               trans.AddNewlyCreatedDBObject(insert, true);
               projCrv.Dispose();
               trans.Commit();


           } 

       }

Link to comment
Share on other sites

Time was limited so there is ridiculously minimal testing and error checking, but:

 

        [CommandMethod("rdap")]
       static public void RefDistAlongPath()
       {
           Database db = HostApplicationServices.WorkingDatabase;
           Editor ed = Acad.DocumentManager.MdiActiveDocument.Editor;
           using (Transaction trans = db.TransactionManager.StartTransaction())
           {
               // Put your command code here
               PromptEntityOptions peo = new PromptEntityOptions("Select target curve: ");
               peo.SetRejectMessage("\nPlease only select a curve entity!");
               peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Curve), false);
               PromptEntityResult per = ed.GetEntity(peo);
               if (per.Status != PromptStatus.OK) return;
               ObjectId oid = per.ObjectId;
               Curve crv = (Curve)trans.GetObject(oid, OpenMode.ForRead, false);
               Plane pl = new Plane(ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Origin, ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis);
               Curve projCrv = crv.GetOrthoProjectedCurve(pl);
               PromptStringOptions pso = new PromptStringOptions("Enter name of block to create reference: ");
               PromptResult pr = ed.GetString(pso);
               String blkName = pr.StringResult;
               BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);     
               if (!bt.Has(blkName)) 
               { 
                   ed.WriteMessage ("Current Database does not contain a block of that name!");
                   return;
               }
               BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[blkName], OpenMode.ForRead);
               PromptDistanceOptions pdo = new PromptDistanceOptions("Indicate distance along path: ");
               pdo.AllowArbitraryInput = false;
               PromptDoubleResult pdr = ed.GetDistance(pdo);
               if (pdr.Status != PromptStatus.OK) return;
               Point3d p3d = projCrv.GetPointAtDist(pdr.Value);
               Vector3d v3d = projCrv.GetFirstDerivative(p3d);
               Double ang = Math.Atan(v3d.Y / v3d.X);
               BlockTableRecord currSpace = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
               BlockReference insert = new BlockReference(p3d, btr.ObjectId);
               insert.Rotation = ang;
               currSpace.AppendEntity(insert);
               insert.SetDatabaseDefaults();
               trans.AddNewlyCreatedDBObject(insert, true);
               projCrv.Dispose();
               trans.Commit();


           } 

       }

 

 

I'm working on something similar at home where I also use C#. Can't give you any feedback until I do return home - no Visual Studio to compile it here at work.

 

Thanks for your time :)

Link to comment
Share on other sites

quick and dirty

;;;inserts a block at specified station along a polyline, measured from start LPS 2009

(defun c:test ()
 (vl-load-com)
(defun rtd (a) (/ (* a 180.0) pi))
 (setq oldosnap (getvar "osmode"))
 (setvar "osmode" 0)
 (command "ucs" "w")
 (setq    ob     (entsel "Select curve: ")
   dist   (getreal "\n Specify Distance from beginning of curve : ")
   obj    (vlax-ename->vla-object (car ob))
   pt1    (vlax-curve-getPointAtDist obj dist)
   param1 (vlax-curve-getParamAtPoint obj pt1)
   deriv1 (vlax-curve-getFirstDeriv obj param1)
   ang    (rtd (angle '(0 0) deriv1))
 ) ;_ end of setq
 (command "-insert" "[color=Red]BLOCKNAME[/color]" pt1 "" ang)
 (command "ucs" "p")
 (setvar "osmode" oldosnap)
 (princ)
) ;_ end of defun

Link to comment
Share on other sites

Or even a more ancient style:

 

[b][color=BLACK]([/color][/b]defun c:mscopy [b][color=FUCHSIA]([/color][/b]/ n d ln lc ss i en[b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]not n[b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]setq n [b][color=MAROON]([/color][/b]getstring [color=#2f4f4f]"\nBLOCK To INSERT:   "[/color][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]cond [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]not [b][color=BLUE]([/color][/b]snvalid n[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b]
               [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nInvalid Block Name - "[/color] n[b][color=GREEN])[/color][/b]
               [b][color=GREEN]([/color][/b]setq n nil[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b]
              [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]tblsearch [color=#2f4f4f]"BLOCK"[/color] n[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b]
              [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]findfile [b][color=BLUE]([/color][/b]strcat n [color=#2f4f4f]".DWG"[/color][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b]
               [b][color=GREEN]([/color][/b]command [color=#2f4f4f]"_.INSERT"[/color] n[b][color=GREEN])[/color][/b]
               [b][color=GREEN]([/color][/b]command[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b]
              [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]setq n nil[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]initget 7[b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]setq d [b][color=NAVY]([/color][/b]getdist [color=#2f4f4f]"\nMeasure Segment Length:   "[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]setq ln [color=#2f4f4f]"TEMP1"[/color] lc 1[b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]tblsearch [color=#2f4f4f]"LAYER"[/color] ln[b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]setq lc [b][color=MAROON]([/color][/b]1+ lc[b][color=MAROON])[/color][/b] ln [b][color=MAROON]([/color][/b]strcat [color=#2f4f4f]"TEMP"[/color] [b][color=GREEN]([/color][/b]itoa lc[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]command [color=#2f4f4f]"_.LAYER"[/color] [color=#2f4f4f]"_M"[/color] ln [color=#2f4f4f]""[/color][b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]= [b][color=MAROON]([/color][/b]getvar [color=#2f4f4f]"CMDACTIVE"[/color][b][color=MAROON])[/color][/b] 0[b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]command [color=#2f4f4f]"_.MEASURE"[/color] pause[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]command [color=#2f4f4f]"_B"[/color] n [color=#2f4f4f]"_Y"[/color] d[b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]setq ss [b][color=NAVY]([/color][/b]ssget [color=#2f4f4f]"X"[/color] [b][color=MAROON]([/color][/b]list [b][color=GREEN]([/color][/b]cons 8 ln[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]command [color=#2f4f4f]"_.CHANGE"[/color] ss [color=#2f4f4f]""[/color] [color=#2f4f4f]"_P"[/color] [color=#2f4f4f]"_E"[/color] 0.0 [color=#2f4f4f]""[/color]
          [color=#2f4f4f]"_.ERASE"[/color] ss [color=#2f4f4f]""[/color][b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]setq i [b][color=NAVY]([/color][/b]sslength ss[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]not [b][color=MAROON]([/color][/b]minusp [b][color=GREEN]([/color][/b]setq i [b][color=BLUE]([/color][/b]1- i[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]setq en [b][color=MAROON]([/color][/b]ssname ss i[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]entdel en[b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]getstring [color=#2f4f4f]"\nPress Enter To Continue:   "[/color][b][color=NAVY])[/color][/b]
        [b][color=NAVY]([/color][/b]entdel en[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]prin1[b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b]

-David

Link to comment
Share on other sites

Only being able to place a block from the start of the line means it's not really usable for my needs. Having to hard wire the block is also a fundamental draawback.

 

Any way we can address these two points? Maybe select an existing block in the drawing to move or choose a block from a file; and then choose a point on the polyline to move it from.

 

Sorry to be cheeky.:D

Link to comment
Share on other sites

You normally give good advice. But learning LISP now is analogous to wearing a mullet in the late 90's.
O RLY? Actually that's the sort of comments you would hear about LISP back then.
Link to comment
Share on other sites

Only being able to place a block from the start of the line means it's not really usable for my needs.

 

Ah, I based the measured position on the startpoint of the curve as well.

 

It sounds like the routine I posted above will not handle all the requirements. Just as well – I rushed to post that before leaving the desk this morning and it likely contains all manner of disappointments. I really should know better.

 

If I get some time this weekend I’ll see what I can do to refine it a bit.

Link to comment
Share on other sites

As I eventually came to expect, my earlier posting has it’s problems. One of which is the inability to process LightWeight Polylines. Not insurmountable, necessarily, but requiring a geometry restructure.

 

When you say:

 

My application is about copying a block along a path e.g a road, railway etc. where the path has many intricate curves and 3D movements. All I want to do is copy a block X amount of distance along the line in plan view, ignoring Z values.

 

What type of geometry are you dealing with – 3dPolys, Splines? I don’t imagine either LightWeight or 2D polys would be useful with the natural undulations of a countryside.

Link to comment
Share on other sites

As I eventually came to expect, my earlier posting has it’s problems. One of which is the inability to process LightWeight Polylines. Not insurmountable, necessarily, but requiring a geometry restructure.

 

When you say:

 

 

 

What type of geometry are you dealing with – 3dPolys, Splines? I don’t imagine either LightWeight or 2D polys would be useful with the natural undulations of a countryside.

 

2D/3D polylines mainly when we're using models created in other sof****re (MX for roads etc). At the moment I have to copy the 3D versions and then convert them to 2D to successfully use the measure and divide etc after I've trimmed them down etc.

 

I've got the tools to do the job, and I'm working on alternatives in .NET myself.Although I wan't to be better at the general application of C# before I really get stuck in with CAD - which is my rationale for learning the language.

Link to comment
Share on other sites

this might work, after switching to c3d, i had to rewrite the retired land desktop command "continuous copy". i finally got around to doing it friday.

you are more than welcome to it if it's what you need.

 

;;; ------------------------------------------------------------------------
;;;    ContinuousCopy.lsp
;;;
;;;    Copyright© 03.06.09
;;;    Alan J. Thompson (alanjt)
;;;
;;;    Permission to use, copy, modify, and distribute this software
;;;    for any purpose and without fee is hereby granted, provided
;;;    that the above copyright notice appears in all copies and
;;;    that both that copyright notice and the limited warranty and
;;;    restricted rights notice below appear in all supporting
;;;    documentation.
;;;
;;;    Modeled after the Land Desktop 'retired' "Continuous Copy" command
;;;    (some coding borrowed from original Land Desktop routine).
;;;    User is able to continuously copy selected object(s) along a
;;;    defined angle & distance. Distance may be changed at any time.
;;;
;;; ------------------------------------------------------------------------

(defun c:CC () (c:ContinuousCopy))
(defun c:ContinuousCopy
      (/ *error* #OldCmdecho #CopyGroup #Angle #Dist #Temp #Ent)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;error handler
 (defun *error* (msg)
   (if    #OldCmdecho
     (setvar "cmdecho" #OldCmdecho)
   )
 ) ;_ defun


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN ROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (setq #OldCmdecho (getvar "cmdecho"))
 (setvar "cmdecho" 0)

 (prompt "\nContinuous Copy")
 (if
   (and
     (setq #CopyGroup (ssget ":L"))
     (setq #Angle (getangle "\nAngle for copy: "))
     (setq #Dist (getdist "\nDistance to copy: "))
     (setq #Temp (strcat
           "@"
           (rtos #Dist 2 6)
           "<"
           (angtos #Angle 0 4)
         ) ;_ strcat
     ) ;_ setq
   ) ;_ and
    (while
      (not
    (member #Temp
        (list "Exit" "X" "Quit")
    ) ;_ member
      ) ;_ not
   (setq #Ent (entlast))
   (vl-cmdf "_.copy" #CopyGroup "" "0,0" #Temp)
   (initget 0 "Exit X Quit")
   (setq #Temp (getdist (strcat
                  "\nDistance to copy <"
                  (rtos #Dist 2 2)
                  ">: "
                ) ;_ strcat
           )
   ) ;_ setq
   (if
     (and
       #Temp
       (not
         (member #Temp
             (list "Exit" "X" "Quit")
         ) ;_ member
       ) ;_ not
     ) ;_ and
      (setq #Dist #Temp)
   ) ;_ if
   (if
     (not
       (member #Temp
           (list "Exit" "X" "Quit")
       ) ;_ member
     ) ;_ not
      (progn
        (setq #Temp (strcat
              "@"
              (rtos #Dist 2 6)
              "<"
              (angtos #Angle 0 4)
            ) ;_ strcat
        ) ;_ setq
        (setq #CopyGroup (ssadd))
        (while
          (setq #Ent (entnext #Ent))
       (if #Ent
         (setq #CopyGroup (ssadd #Ent #CopyGroup))
       ) ;_ if
        ) ;_ while
      ) ;_ progn
   ) ;_ if
    ) ;_ while
    (princ "\nMissed, try again.")
 ) ;_ if

 (setvar "cmdecho" #OldCmdecho)

 (princ)
) ;_ defun
;|«Visual LISP© Format Options»
(72 2 40 2 T nil 60 9 0 0 0 T T nil T)
;*** DO NOT add text below the comment! ***|;

Edited by alanjt
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...