Author Topic: An AutoLISP/AutoCAD oddity... (also: multiple join layers LISP routine)  (Read 7258 times)

0 Members and 1 Guest are viewing this topic.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
So, I've been using this routine for quite some time - been through several rewrites (original only let you select one layer). After my last rewrite to allow for multiple select to process several layers, I noticed a strange error. I never investigated it and would just limit my selections. today, I decided to figure out why I was receiving an invalid ssget list error. I finally found that I was somehow selecting an entity that nil'ed when dumping it's entity data with entget. I decided to change the 'check' to see if the object actually returns an error before checking it against a list of already processed layers.

Thought the find was really weird and thought I'd share.

Here's the problem version:
Code: [Select]
(defun c:MJL (/ ss)
  ;; Join all on selected object(s)' layer
  ;; Alan J. Thompson, 09.09.10
  (if (setq ss (ssget "_:L"))
    ((lambda (i ctab / e la lst all)
       (while (setq e (ssname ss (setq i (1+ i))))
         (or (vl-position (cdr (setq la (assoc 8 (entget e)))) lst)
             (and (setq lst (cons la lst))
                  (setq all (ssget "_X" (list '(0 . "ARC,LINE,LWPOLYLINE") ctab la)))
                  (if (eq (getvar 'peditaccept) 1)
                    (vl-cmdf "_.pedit" "_m" all "" "_J" "" "")
                    (vl-cmdf "_.pedit" "_m" all "" "_Y" "_J" "" "")
                  )
             )
         )
       )
     )
      -1
      (cons 410 (getvar 'ctab))
    )
  )
  (princ)
)

and here's the rewrite I did today:
Code: [Select]
(defun c:MJL (/ pedit 4ten ss i l lst all)
  ;; Join all on selected object(s)' layer
  ;; Alan J. Thompson, 06.28.11

  (if (setq pedit (eq (getvar 'PEDITACCEPT) 1)
            4ten  (if (eq (getvar 'CVPORT) 1)
                    (cons 410 (getvar 'CTAB))
                    (cons 410 "Model")
                  )
            ss    (ssget "_:L")
      )
    (repeat (setq i (sslength ss))
      (if (and (setq l (assoc 8 (entget (ssname ss (setq i (1- i))))))
               (not (vl-position l lst))
               (setq all (ssget "_X"
                                (list '(0 . "ARC,LINE,LWPOLYLINE")
                                      4ten
                                      (car (setq lst (cons l lst)))
                                )
                         )
               )
          )
        (if pedit
          (vl-cmdf "_.pedit" "_m" all "" "_J" "" "")
          (vl-cmdf "_.pedit" "_m" all "" "_Y" "_J" "" "")
        )
      )
    )
  )
  (princ)
)
« Last Edit: June 28, 2011, 05:00:48 PM by alanjt »
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: An AutoLISP/AutoCAD oddity...
« Reply #1 on: June 28, 2011, 04:58:06 PM »
And no, changing from while to repeat was not what fixed the error. It was one of my attempts, but the fix was checking to see if the object could be dumped with entget. From there, I just left it using repeat because I didn't feel like typing everything again.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
I understand this is just a discussion but I'm not sure if I can still discuss much "speaking AutoLisp" but I'll give it a shot.

The following is cut from a routine which I needed to do some checking like what you describe (or what I --think-- I see from your first code example.

So my question is: couldnt you adopt a similar process and just remove all items which have similar layers? -i.e. build list(s), process list, filter list, do change.

Get the items
Get their layers
remove dup items (from above)
...

Code: [Select]
;;  Pseudo Code:
;;  ------------
;;  o Select an ent(s)
;;  o Get layers from those ents
;;  ~ Clean up list of layers by removing dups
;;  ...

(defun Select-Ent-lst ( )
  (
   ;; Itterate thru a Selection Set and return a list of items
   ;; used to allow end user to select some items they wish to keep
   (lambda (ss / lst cntr)
     (if (null cntr)
       (setq cntr 0) )
     (if (null lst)
       (setq lst '()) )
      (if (eq (type ss) 'PICKSET)
        (repeat (sslength ss)
           (setq lst (append lst (list (entget (ssname ss cntr)))))
           (setq cntr (1+ cntr)))
        '*ERROR* )
     lst
     )
    (ssget)) )

(defun build-Layer-lst ( ent-lst )
  (mapcar
   ;; Build a list of layers
   '(lambda (x) (cdr (assoc 8 x))) ent-lst) )

(defun clean-lst ( my-lst / lst )
 ;; Clean up a list of items; remove duplicates
     (foreach x my-lst
       (if (not (member x lst))
         (setq lst (cons x lst))))
     (reverse lst) )

TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
bullet
bullet
tilde?
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
yeah, the tilde meant something or another at one time but i switched to a different format of pseudo code years ago and i dont have that old "pesudo code key plan" any longer.  and to be honest, i dont even use this format since i lost everything a while back much either but "now" my pseudo code looks more like C. *lol*

Code: [Select]
Symbol Key:
*    =     Subject.
-    =     Task / Procedure
[    =     Begin loop
]    =     End loop
{    =     Begin block of code
}    =     End block of code

* PSEUDOCODE:
<snip>
     {
          find layer
              locate layer in drawing
              { switch
                    case: if layer !exist
                          {
                                  find layer file
                                          parse layer file
                                          create layer
                          }
<snip>

TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
yep, that explains it
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
That anaphore scares me. What do you mean by `it'?

Ref:
Quote
'"...and even Stigand, the patriotic archbishop of Canterbury, found it advisable--"'
'Found what?' said the Duck.
'Found it,' the Mouse replied rather crossly: 'of course you know what "it" means.'
'I know what "it" means well enough, when I find a thing,' said the Duck: 'it's generally a frog, or a worm. The question is, what did the archbishop find?'
[Lewis Carroll, Alice's Adventures in Wonderland, Chapter III]

:D
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
That anaphore scares me. What do you mean

when my dad eats he sounds like a pig

 :lmao: That was hilarious  :lol: Was that Will Ferrell on the front row?

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
*blink* ...tough crowd i guess (another one of my jokes missed its mark).
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

mjfarrell

  • Seagull
  • Posts: 14444
  • Every Student their own Lesson
*blink* ...tough crowd i guess (another one of my jokes missed its mark).
Still laughing over here.....  :lmao:
Be your Best


Michael Farrell
http://primeservicesglobal.com/

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Question Alan, just starting to look at the code.
In my ACAD2006 (getvar 'CTAB) returns "Model" only when in the model space tab & not in paper space, active vp or not.
Is that not true for newer versions?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Question Alan, just starting to look at the code.
In my ACAD2006 (getvar 'CTAB) returns "Model" only when in the model space tab & not in paper space, active vp or not.
Is that not true for newer versions?
It would be that way for all versions. If you notice, I only call for (getvar 'CTAB) when (getvar 'CVPORT is equal to 1, anything else I use (410 . "Model")....or am I missing something?
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
All I use is :
Code: [Select]
               (setq all (ssget "_X"
                                (list '(0 . "ARC,LINE,LWPOLYLINE")
                                      (cons 410 (getvar 'CTAB))
                                      (car (setq lst (cons l lst)))
                                )
                         )
               )
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Code: [Select]
needs
                                more
                                                                tabs
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
All I use is :
Code: [Select]
               (setq all (ssget "_X"
                                (list '(0 . "ARC,LINE,LWPOLYLINE")
                                      (cons 410 (getvar 'CTAB))
                                      (car (setq lst (cons l lst)))
                                )
                         )
               )
What if you are working in a viewport?

Code: [Select]
needs
                                more
                                                                tabs
and cowbell!
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Quote
What if you are working in a viewport?
Still returns the Tab Name, but if you are in an active VP your method get all of model space not just what you see.
I always move to Model space, seldom do anything through the vp that affects all of model space.
I now see your intent though. Just not the way I work.  8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Quote
What if you are working in a viewport?
Still returns the Tab Name, but if you are in an active VP your method get all of model space not just what you see.
I always move to Model space, seldom do anything through the vp that affects all of model space.
I now see your intent though. Just not the way I work.  8-)
I rarely ever work through the viewport (find it to be bad practice), but even I go against my own practices and when I do, I want it to select properly.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Pad

  • Bull Frog
  • Posts: 342
Re: An AutoLISP/AutoCAD oddity... (also: multiple join layers LISP routine)
« Reply #18 on: March 01, 2012, 08:58:30 AM »

and here's the rewrite I did today:
Code: [Select]
(defun c:MJL (/ pedit 4ten ss i l lst all)
  ;; Join all on selected object(s)' layer
  ;; Alan J. Thompson, 06.28.11

  (if (setq pedit (eq (getvar 'PEDITACCEPT) 1)
            4ten  (if (eq (getvar 'CVPORT) 1)
                    (cons 410 (getvar 'CTAB))
                    (cons 410 "Model")
                  )
            ss    (ssget "_:L")
      )
    (repeat (setq i (sslength ss))
      (if (and (setq l (assoc 8 (entget (ssname ss (setq i (1- i))))))
               (not (vl-position l lst))
               (setq all (ssget "_X"
                                (list '(0 . "ARC,LINE,LWPOLYLINE")
                                      4ten
                                      (car (setq lst (cons l lst)))
                                )
                         )
               )
          )
        (if pedit
          (vl-cmdf "_.pedit" "_m" all "" "_J" "" "")
          (vl-cmdf "_.pedit" "_m" all "" "_Y" "_J" "" "")
        )
      )
    )
  )
  (princ)
)


Hi Alan.  this is a very useful routine.  Wondered if it was possible to add a check on the linetype to the mix.  So that if two polylines which are on the same layer but one is continuous linetype and the other hidden then they aren't joined.  Cheers P

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: An AutoLISP/AutoCAD oddity... (also: multiple join layers LISP routine)
« Reply #19 on: March 01, 2012, 11:41:08 AM »
Alan, the error is obvious, you are tying to entget entities that were already pedited/joined and therefore deleted
think of two "connected" lines on the same layer as the initial selection set
« Last Edit: March 01, 2012, 12:09:40 PM by VovKa »