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

A very messy lisp

5 REPLIES 5
Reply
Message 1 of 6
rodb
395 Views, 5 Replies

A very messy lisp

Hi, Happy New Year all.

 

Here is a very messy program. I wonder if anyone would like to sort it out? It is supposed to search for all blocks with  attribute CIRCUIT with a certain value and place a mark at the attribute text insert point, actually I wonder if it could place the point on the middle centre of the attribute text?

 

(defun restore () ;restore variables
(command "layer" "set" cly "")
(setvar "cmdecho" cmd)
(setvar "osmode" osm)
(setvar "expert" etp)
(setq *error* olderr)
(princ)
)
(defun trap (er) ;error trapping
(princ "\nPROGRAM ABORTED ")
(princ er)
(command "layer" "set" cly "")
(setvar "cmdecho" cmd)
(setvar "osmode" osm)
(setvar "expert" etp)
(setq *error* olderr)
(princ)
)

(defun cmark (/ a v e)
(graphscr)
(setq a "CIRCUIT")
(setq v (getstring 2 "\nWhat value does the circuit have.. "))
(setq e (entnext))

(prompt "\nSearching for Circuit with value ")
(princ v)
(princ "\nworking......")
(princ)
(while e
(setq atrib (cdr (assoc 2 (entget e))))
(setq value (cdr (assoc 1 (entget e))))
(if
(and
(equal atrib a)
(equal value v))
(progn
(setq pt (cdr (assoc 10 (entget e))))
(command "point" pt)
(setq ct (+ ct 1))
)
)
(setq e (entnext e))
)
(princ "There are ")
(princ ct)
(princ " Fittings with attribute ")
(princ a)
(princ " and value ")
(princ v)
(restore)
)
(defun laymake()
(graphscr)
(setq osm (getvar "osmode")
cmd (getvar "cmdecho")
cly (getvar "clayer")
etp (getvar "expert")
olderr *error*
*error* trap
ct 0)
(setvar "cmdecho" 0)
(setvar "expert" 4)
(setvar "pdmode" 35)
(setvar "pdsize" -10)
(setvar "osmode" 0)
(setq ln (tblsearch "layer" "AQ_CIRCUITMARK")) ;check for layer & make it
(if (= ln nil)
(command "layer" "M" "AQ_CIRCUITMARK" "C" "YELLOW" "" "")
)
(command "layer" "THAW" "AQ_CIRCUITMARK" "ON" "AQ_CIRCUITMARK" "S" "AQ_CIRCUITMARK" "")
(command "ZOOM" "extents" )
(cmark)
)

5 REPLIES 5
Message 2 of 6
Kent1Cooper
in reply to: rodb


@RodB wrote:

.... 

Here is a very messy program. I wonder if anyone would like to sort it out? It is supposed to search for all blocks with  attribute CIRCUIT with a certain value and place a mark at the attribute text insert point, actually I wonder if it could place the point on the middle centre of the attribute text?

....


A couple of questions....

 

Everything in there seems to be a function or subroutine, with no actual Command defined.  It appears that to use it, you would need to type in [or invoke from some other code]

(laymake)

which seems a strange identifier, considering what it all does.  Might not the "cmark" serve as a better "name" for it, and defined as a Command so you don't need to use parentheses around it if you type it in?

 

Can you redefine the Blocks so that the Attributes are Middle-justified?  That would make the points appear where you want them, located directly from the insertion points as currently coded.  It would be rather more complicated otherwise, involving getting the bounding box of each Attribute and calculating the middle of that.  But maybe you need that, if it's not practical to redefine Blocks.

Kent Cooper, AIA
Message 3 of 6
Kent1Cooper
in reply to: rodb


@RodB wrote:

....Here is a very messy program. I wonder if anyone would like to sort it out? ....


Here's a version that simplifies some aspects, does without a few unneeded variables, and does various things in the ways I would probably do them [but not all -- there are a few lesser things I'd probably do a little differently if I were starting from scratch].  The mid-point-of-the-Attribute Point location didn't take as much extra as I was anticipating.  Write back if you don't understand why I made any particular change.

 

Type CMARK [not case-sensitive], without parentheses, to use it.  Minimally tested.

 

(defun C:CMARK (/ *error* restore osm cmd cly etp ct a v e); = Circuit MARKers

  (defun *error* (er)
    (prompt (strcat "\nPROGRAM ABORTED: " er))
    (restore)
  ); defun - *error*

  (defun restore (); restore variables
    (setvar 'clayer cly)
    (setvar 'cmdecho cmd)
    (setvar 'osmode osm)
    (setvar 'expert etp)
    (princ)
  ); defun - restore

  (graphscr)
  (setq
    osm (getvar 'osmode)
    cmd (getvar 'cmdecho)
    cly (getvar 'clayer)
    etp (getvar 'expert)
    ct 0
    a "CIRCUIT"
    v (strcase (getstring T "\nValue of Circuit: "))
      ; not case-sensitive [remove (strcase) function if you want it to be]
    e (entnext)
  ); setq
  (setvar 'cmdecho 0)
  (setvar 'expert 4)
  (setvar 'pdmode 35)
  (setvar 'pdsize -10)
  (setvar 'osmode 0)
  (command
    "_.layer" "_thaw" "AQ_CIRCUITMARK" "_make" "AQ_CIRCUITMARK" "_color" 2 "" ""
    "_.zoom" "_extents"
  ); command
  (prompt (strcat "\nSearching for Circuit with value " v ".\nworking......"))
  (while e
    (if
      (and
        (= (cdr (assoc 2 (entget e))) a)
        (= (strcase (cdr (assoc 1 (entget e)))) v)
          ; not case-sensitive [remove (strcase) function if you want it to be]
      ); and
      (progn ; then
        (vla-getboundingbox (vlax-ename->vla-object e) 'minpt 'maxpt)
        (setq
          LL (vlax-safearray->list minpt); = Lower Left
          UR (vlax-safearray->list maxpt); = Upper Right
          ct (1+ ct)
        ); setq
        (command "_.point" (mapcar '/ (mapcar '+ LL UR) '(2 2 2))); halfway between
      ); progn
    ); if
    (setq e (entnext e))
  ); while
  (prompt (strcat "\n" (itoa ct) " Fitting(s) found with attribute " a " and value " v "."))
  (restore)
); defun - C:CMARK

Kent Cooper, AIA
Message 4 of 6
rodb
in reply to: Kent1Cooper

Hi, Thats looking much neater thank you. The circuit attributes text is middle center justified but in thinking about it each bloack has about 15 attributes, 5 0f which would be searched for so I feel the best bet would be to place a point on the insert point of the blocks that contain the circuit you are looking for that would indicate the block itself but means storing that point for every block found on the way to finding the ones with the circuit you want. 

 

I made the layer function separate just for my own clarity like a sub-routine and yes I could define the main body as a command using C:CMARK. Would it not be faster to use ssget X (0.INSERT) to find all the blocks in the drawing as they way I wrote it a long time ago it steps through all the entities in the drawing which could be many thousands?

 

Is it possible to do an ssget and directly find blocks with circuit attribute of a certain value? Or even just blocks with a circuit attribute and then check for the right ones?  

Message 5 of 6
Kent1Cooper
in reply to: rodb


@RodB wrote:

.... 

Is it possible to do an ssget and directly find blocks with circuit attribute of a certain value? Or even just blocks with a circuit attribute and then check for the right ones?  


You can filter in (ssget) for Blocks, but not, as far as I know, for tags or values of Attributes within them.  But you could at least tie it down a little tighter by filtering for only Blocks that contain Attributes:

 

(ssget "_X" '((0 . "INSERT") (66 . 1)))

 

Ordinary dumb Blocks don't have that (66 . 1) entry in ther entity data, the way Blocks with Attributes do.

 

That would still leave you to step through looking for the right Attributes, but there would be less work to do.

Kent Cooper, AIA
Message 6 of 6
rodb
in reply to: rodb

Thanks that will be much better! I did not know about the 66 assoc, very useful. 

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

Post to forums  

Autodesk Design & Make Report

”Boost