Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Lisp Routine using the Measure command

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
Anonymous
2953 Views, 11 Replies

Lisp Routine using the Measure command

Can you use Lisp to Measure a Polyline without having to select it? Something like

Having just drawn the Lpoly

 

(setq ep enget)

(setq space (getint "\n Enter spacing"))

(command "measure" ep Block "myblock" space "")

 

AutoCAD seems to insist on making you select the object to measure manually. Its always been a problem for me.....

 

 

 

 

 

11 REPLIES 11
Message 2 of 12
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

Can you use Lisp to Measure a Polyline without having to select it? Something like

Having just drawn the Lpoly

 

(setq ep enget)

(setq space (getint "\n Enter spacing"))

(command "measure" ep Block "myblock" space "")

 

AutoCAD seems to insist on making you select the object to measure manually. Its always been a problem for me.....


If you've just drawn it, that first line should be

(setq ep (entlast))

 

If you want to select it, but not within the Measure command, and have it fed into that, try:

(setq ep (entget))

(setq space (getint "\n Enter spacing"))

(command "measure" (car ep) "Block" "myblock" space "")

 

Read about what (entget) actually returns to see why.

 

I would think (getdist) is a better function for the spacing, since it allows other-than-whole-number values that (getint) won't, and you have the option to specify the distance either by typing something or picking two points on-screen.

Kent Cooper, AIA
Message 3 of 12
Anonymous
in reply to: Kent1Cooper

Hi,

 

when I run this

(setq ep (entlast))
(setq space (getint "\n Enter spacing"))
(command "measure" (car ep) "Block" "myblock" space "")

 

I get this.

Select object to measure: ; error: bad argument type: consp <Entity name: 7ffffb0a4c0>

 

I have made the block myblock in the dwg.

If I do this

!ep

I get

<Entity name: 7ffffb0a4c0>

If I do this

(setq check (car ep))

I get this

; error: bad argument type: consp <Entity name: 7ffffb0a4c0>

 

What I don't understand is that this works perfectly

 

(command "area" "e" ep)
      (command "chprop" ep "" "c" "30" "")
      (command "pedit" ep "w" llwid "")
    (command "chprop" ep "" "LT" "LL" "")

 

Its just the measure command that won't accept ep passed to the select objects command.

I don't want to pause to manually select the pline because its part of a much larger program and it may even be difficult to find the last drawn pline. And I also want to force the space variable to only accept integers and not accept two points either. You have to type it in.

 

 

Message 4 of 12
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

.... 

when I run this

(setq ep (entlast))
(setq space (getint "\n Enter spacing"))
(command "measure" (car ep) "Block" "myblock" space "")

 

I get this.

Select object to measure: ; error: bad argument type: consp <Entity name: 7ffffb0a4c0>

.... 

Its just the measure command that won't accept ep passed to the select objects command.

 

I don't want to pause to manually select the pline ... and it may even be difficult to find the last drawn pline. ....


I should changed your 'enget' to (entsel) rather than just adding the t and parentheses to make (entget) [I just ran with the visual of the misspelling of a function name and its not having parentheses, without noticing it was also the wrong function for the purpose], and I should have have suggested reading about (entsel) instead of (entget).


You've mixed together elements of two different suggestions.  The (entlast) function returns an entity name; (entsel) returns a list of an entity name and the point at which it was selected.  The Measure command is going to require that you give it an entity name.  I suggested using (entlast) "If you've just drawn it," because of your prefacing your code with "Having just drawn the Lpoly."  That would put the last-drawn entity's name into the 'ep' variable.

 

I suggested the code that uses (car ep) only "If you want to select it," which I assume would be needed if it's not necessarily the last-drawn entity.  That, after using the should-have-said (entsel) rather than (entget), pulls the entity name out of the list that (entsel) returns, to give it to the Measure command.  In your code above, where 'ep' is already an entity name as returned by (entlast), Measure would accept just ep rather than (car ep).  [That's assuming, of course, that the last entity is something Measure can be applied to.]  The error message is because (car) is looking for the first item in a list [that's what 'consp' tests for], and the entity name in 'ep' isn't a list.  The 'ep' variable will contain a list if it's set by (entsel) instead, but that requires User selection.

 

As for your last sentence quoted above, that conflicts with your original post in which you talk about having just drawn it.  If it may not be the last thing drawn, then I don't see how you're going to identify it without manually selecting it, unless, for example, it will always be at exactly the same location, or will be the only thing on its Layer, or there's something else about it that can distinguish it from everything else.

Kent Cooper, AIA
Message 5 of 12
BeKirra
in reply to: Anonymous


@Anonymous wrote:

Can you use Lisp to Measure a Polyline without having to select it? Something like

Having just drawn the Lpoly

 

(setq ep enget)

(setq space (getint "\n Enter spacing"))

(command "measure" ep Block "myblock" space "")

 

AutoCAD seems to insist on making you select the object to measure manually. Its always been a problem for me.....

 


Logically what you're trying to do will not work.

Without selecting a lwpline you can only measure it if you know its entity name.

An entity name is something like:

Entity name: 7ffffb1c980

 

HTH

Please mark "Accept as Solution" and "Like" if my reply resolves the issue and it will help when others need helps.
= ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ = ♪ = ♫ =
A circle is the locus of a cursor, starting and ending at the same point on a plane in model space or in layout such that its distance from a given coordinates (X,Y) is always constant.
X² + Y² = C²
Message 6 of 12
Anonymous
in reply to: BeKirra

I'm sorry I have not been able to clearly explain my problem.

 

Firstly I definately do not want to have to select the polyline.

 

this works with all these commands

 

      (setq ep (entlast))

      (command "area" "e" ep)
      (command "chprop" ep "" "c" "30" "")
      (command "pedit" ep "w" llwid "")
    (command "chprop" ep "" "LT" "LL" "")

 

All those commands also require you to pick an object but by using "ep" you don't have to pick anything.

 

But this does not work
    (setq ep (entlast))
    (setq seglen (getint "\nSegment length"))
    (command "measure" ep "Block" "tapemarks" seglen "")

Both Measure and Divide do not accept ep so they must expect something else unlike the other commands above. They also expect only one object but that applies to area as well.

 

So how do you pass the last object drawn to the measure command without manually selecting it?

 

!ep returns this <Entity name: 7ffffb0a0a0>

 

This has been a thorn in my side for many years so frustrating why have they made measure work differently?

 

 

 

 

 

 

Message 7 of 12
hmsilva
in reply to: Anonymous

Hi rodb,

 

as a demo, I did add some if's and prompts to show what has failed.

Change myblock, to the correct one...

 

(vl-load-com)
(defun c:demo (/ ans ent lastpoly pt_lst space)
  (if (and (setq lastpoly (entlast))
           (setq ent (entget lastpoly))
      );; and
    (if (= (cdr (assoc 0 ent)) "LWPOLYLINE")
      (if (tblsearch "BLOCK" "myblock")
        (if (progn (initget 6)
                   (setq space (getdist "\n Enter spacing: "))
            )
          (if (>= (vlax-curve-getDistAtParam lastpoly (vlax-curve-getEndParam lastpoly)) space)
            (progn
              (setq pt_lst (vl-remove-if-not '(lambda (x) (member (car x) '(10))) ent))
              (initget "Start End")
              (setq ans (getkword "\n Measure polyline, from start or from end [Start End] <exit>: "))
              (cond ((and ans
                          (wcmatch ans "Start")
                     )
                     (command "_.measure" (list lastpoly (cdr (car pt_lst))) "_B" "myblock" "_Y" space)
                     (prompt "\nLast LwPolyline was mesured from the beginning... ")
                    )
                    ((and ans
                          (wcmatch ans "End")
                     )
                     (command "_.measure" (list lastpoly (cdr (last pt_lst))) "_B" "myblock" "_Y" space)
                     (prompt "\nLast LwPolyline was mesured from the end... ")
                    )
                    (T
                     (prompt "\n Exiting... ")
                    )
              )
            )
            (prompt "\n Spacing longer than LwPolyline ... ")
          );; if
          (prompt "\n User didn't enter spacing... ")
        );; if
        (prompt "\n Myblock wasn't found in drawing database... ")
      );; if
      (prompt "\n Last entity is not a LwPolyline... ")
    );; if
    (prompt "\n This is an empty dwg, there is no last entity... ")
  );; if
  (princ)
)

 

Hope this helps,
Henrique

EESignature

Message 8 of 12
Anonymous
in reply to: hmsilva

Oh my Henrique lol !!!

 

I take it then a simple measure ep is just not possible! How I wish Autodesk had made the measure/divide command work the same way as so many other commands in simple old lisp.

 

I have to go to work now and will print out your answer to take with me on the train.....

 

Thank you very much for all your trouble I can see my porgram is going to get a lot bigger amd more complicated now, for your reference this is the old program which works fine that I want to change to measure the polyline into segments, mark the segments and place multiple blocks on top of each other on the start point containing the circuit and length and wattage of each segment.....all of which is fairly easy to do except for the measure with block command....

 


;Led Flex tape
(defun restore ()                     ;restore variables
      (command "layer" "set" cly "")
      (setvar "cmdecho" cmd)
      (setvar "expert" etp)
      (setvar "attdia" atd)
      (setvar "plinegen" plgen)
      (setq *error* olderr)
      (princ)
)
(defun trap (er)                       ;error trapping
      (princ "\nPROGRAM ABORTED ")
      (princ er)
      (command "layer" "set" cly "")
      (setvar "cmdecho" cmd)
      (setvar "expert" etp)
      (setvar "attdia" atd)
      (setvar "plinegen" plgen)
      (setq *error* olderr)
      (princ)
)
(defun c:LL(/ lgth watts textwatts rlgth)
      (graphscr)
      (setvar "cmdecho" 0)
      (setq ep (entlast))
      (if (equal llwid nil)(setq llwid 30))
    (if (equal llwts nil)(setq llwts 4.8))
    (prompt"\nSet the Wattage per meter..<")
      (princ llwts)
      (princ ">")
      (setq chwts (getreal))
      (if (not (equal chwts nil))(setq llwts chwts))
      (prompt"\nEnter width for LED Light..<")
          (princ llwid)
          (princ ">")
          (setq chwid (getreal))
          (if (not (equal chwid nil))(setq llwid chwid))
      (setq blkno 1)
      (setq blk "LEDFLEX")
      (setq blkname (strcat blk (itoa blkno)))
      (while (tblsearch "block" blkname)
            (setq blkno (+ 1 blkno))
            (setq blkname (strcat blk (itoa blkno)))
       )
    (command "area" "e" ep)
      (command "chprop" ep "" "c" "30" "")
      (command "pedit" ep "w" llwid "")
      (setq lgth (getvar "perimeter"))
    (command "chprop" ep "" "LT" "LL" "")
          (setq fixlgth (fix lgth)
            rlgth (itoa fixlgth)                          
                  watts(* (/ fixlgth 1000.0) llwts)
                  watts(fix watts)
            textwatts (itoa watts))
            
              (command "layer" "S" cly "")
      (setq bp (getpoint "\nPick Basepoint for Attribute Block..."))
      (command "insert" "LVLED_018" bp userr5 userr5 "" "" "" "" textwatts "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" rlgth "")
         (command "-block" blkname bp ep "")
        (command "-insert" blkname bp "1" "1" "0")
              (prompt "\nTotal length of LED tape light is ")
              (princ rlgth)
              (prompt "\nTotal watts of LED tape light is ")
              (princ textwatts)
        (restore)
)

(defun ledflex(/ ln)
      (graphscr)
      (setq osm (getvar "osmode")
            cmd (getvar "cmdecho")
            cly (getvar "clayer")
            etp (getvar "expert")
            atd (getvar "attdia")
            plgen (getvar "plinegen")
            olderr *error*
            *error* trap)
      (setvar "cmdecho" 0)
      (setvar "attdia" 0)
      (setvar "expert" 4)
      (setvar "plinegen" 1)
      (setq ln (tblsearch "layer" "AQ_LOWVOLTS"))   ;check for layer & make it
      (if (= ln nil)
            (command "layer" "M" "AQ_LOWVOLTS" "C" "GREEN" "" "")
      )
      (command "layer" "ON" "AQ_LOWVOLTS" "THAW" "AQ_LOWVOLTS" "S" "AQ_LOWVOLTS" "")
      (prompt"draw your LED rope light using Pline arcs and lines then type LL")
      (prompt "\nPLINE")
      (command "PLINE")
      (princ)
)

Message 9 of 12
hmsilva
in reply to: Anonymous

rodb,

 

your code, works, you'll have to change the 'measure' prompt sequence...

i.e.

(setq ep (entlast))
(setq seglen (getdist "\nSegment length"))
(command "measure" ep "Block" "tapemarks" "_Y" seglen)

 

you'll have to answer to

Align block with object? [Yes/No] <Y>:

with yes ou no, or simply "" ...

 

My 'demo' was just an attempt to demonstrate that providing to the measure command, a list with a ename and a point, we can force the measure from the end, or from the start, but providing to the measure command only the ename, the comand will measure from start...

And we should always validate the data, before using it as an argument...

 

Hope this helps,
Henrique

EESignature

Message 10 of 12
Anonymous
in reply to: hmsilva

Yes I really like the way your lisp is so safe always checking along the way that it will be able to work. I must do that much better than I do at present.

I also like the way its possible to start from the end of the polyline too. The next thing I would like to do is to be able to pick an existing polyline block (the pline is turned into a block so that it can be placed on another layer and either that layer is frozen and or the layer the block was made on is frozen) then explode it, measure it, re-work it as segments, re-block it using the same block name on the same layer and re-work the existing block containing the circuit, wattage and length and turn that into multiple blocks each containing the new circuit, wattage and length values but that is for a very rainy day!

 

Must leave for the train back tomorrow eve so I can get started on Wednesday with it and thanks again!!! 

Message 11 of 12
Anonymous
in reply to: hmsilva

Yep it was that I had not checked the sequence of the measure command and had forgotten the align with option. You would think that by now I would have learned to check the command sequence. Especiallt after using the measure and divide command for so many years. I was convinced it was because the measure command worked differently. Just sloppy programming! Thanks to you its sorted now and I can get on with the rest of the program.

Message 12 of 12
hmsilva
in reply to: Anonymous

You're welcome, robd!
Glad I could help

Henrique

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost