Author Topic: stretch objects on specified layer help  (Read 15485 times)

0 Members and 1 Guest are viewing this topic.

ELOQUINTET

  • Guest
stretch objects on specified layer help
« on: February 23, 2004, 12:58:04 PM »
i have this lisp which works good but i would like to be able to selected multiple layers to stretch. can someone please give me a hint on how to modify it to do so?

Code: [Select]
;Stretch entities on a single layer written: Barry Newlands

(defun c:SL (/ enlay entlst ename olderr selset enum objlen dent layent
 layset lay pt1 pt2 ss ss1 ss2 en osm)

 (if (null myerr)(load "myerr"))
 (setq olderr *error* *error* myerr)
 (setq osm (getvar "osmode"))
 (if (null setvars)(load "setvars"))
  (setq syslst (setvars '(("cmdecho" . 0)
                          ("osmode" . 0)
                          ("trimmode" . 1))
                )
   )
(gc)

(setq dent(list(entsel"\nPICK AN ENTITY ON THE LAYER YOU WISH STRETCHED: ")))
(setq dent(caar dent))
(setq layent(entget dent))
(setq layset(assoc 8 layent))
(setq lay(cdr layset))
(prompt "\n")
(princ lay)
  (setq pt1 (getpoint
   "\n1ST POINT OF STRETCH WINDOW..."))
  (SETQ PT2 (GETCORNER PT1
   "\n....2ND POINT "))
;  (PROMPT "\n<A>DD OR <R>EMOVE OBJECTS:\n")
  (COMMAND "SELECT" "C" PT1 PT2 PAUSE)
  (SETQ SS (SSGET "P"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq objlen(sslength SS))
(setq enum 0)
(setq selset(ssadd))
(repeat objlen
(setq ename(ssname SS enum))
(setq entlst(entget ename))
(setq enlay(assoc 8 entlst))
(setq enlay(cdr enlay))
(if (= enlay lay)
(ssadd ename selset))
(setq enum(+ enum 1))
)
(SETQ SS selset)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  (SETQ SS1 (SSGET "C" PT1 PT2))
  (SETQ SS2 (SSADD))
  (WHILE (SETQ EN (SSNAME SS1 0))
   (IF (NULL (SSMEMB EN SS))
    (SSADD EN SS2)
   )
   (SSDEL EN SS1)
  )
 (setvar "osmode" osm)
  (IF (< 0 (SSLENGTH SS2))
   (COMMAND "SELECT" SS2 ""
    "STRETCH" "C" PT1 PT2 "R" "P" "")
   (COMMAND "STRETCH" "C" PT1 PT2 "")
  )
  (setvars syslst)
  (setq *error* olderr)
  (princ)
)

(defun myerr (msg)
   (if (or (= msg "quit / exit abort")
           (= msg "Function cancelled"))
      (if (and ctl undo_err)   ; if undo_start used and returned value saved
         (undo_err ctl))       ; in ctl then undo everything done so far.
      (princ msg))
   (if (and setvars syslst) ; if usual system var handler and variable exist
      (setvars syslst))     ; then restore system vars
   (setq *error* OLDERR ctl nil)
   (princ)
)

(defun setvars (syslst / oldlst)
   (foreach dp syslst
      (setq oldlst (cons
         (cons (car dp) (getvar (car dp)))
         oldlst)))
   (foreach dp syslst
      (setvar (car dp) (cdr dp))
   )
   oldlst
)


(princ "\nEnter SL to stretch entities on a single layer.")
(princ)


Columbia

  • Guest
stretch objects on specified layer help
« Reply #1 on: February 23, 2004, 04:04:35 PM »
Dan,

Here is a tip that may help you out...

If you have multiple names for the layers you want filter for, here's an easy way of doing it...
Code: [Select]
(ssget (list (cons 8 "LAYER1,LAYER2,LAYER3...")))

So if you use a WHILE loop in your entget area, you could concatenate your layer names into one big string and supply that to the SSGET function.

Do you follow me?

ELOQUINTET

  • Guest
stretch objects on specified layer help
« Reply #2 on: February 23, 2004, 04:25:04 PM »
hmmm think i see the part you're talking about but not sure how to incorporate the line you provided

[/code]  (COMMAND "SELECT" "C" PT1 PT2 PAUSE)
  (SETQ SS (SSGET "P"))
Code: [Select]


am i close and do i just replace the second line with what you provided inserting my layer names???

ELOQUINTET

  • Guest
stretch objects on specified layer help
« Reply #3 on: February 23, 2004, 04:31:20 PM »
whoops can't even post code correctly  :oops: if i understand you correctly i need to put all my layers in a string so it they will be recognized. if i understand you correctly this is a problem. everybody is using their own layers around here and some are job specific so i'd constantly be editing this for it to work. am i reading it correctly?  :cry:

Columbia

  • Guest
stretch objects on specified layer help
« Reply #4 on: February 24, 2004, 10:48:06 AM »
Not exactly... Let me see if I can explain it a little better...

You could put your entity selection in a WHILE loop and have the looping mechanism read the layer into a string.  Like the following:

Code: [Select]

(vl-load-com)

(while (setq ent (entsel "\nSelect entity on layer..."))
  (setq layer_string
    (if layer_string
      (strcat layer_string ","
        (vla-get-layer (vlax-ename->vla-object (car ent)))
      )
      (vla-get-layer (vlax-ename->vla-object (car ent)))
    )
  )
)


Does this make any more sense??

ELOQUINTET

  • Guest
stretch objects on specified layer help
« Reply #5 on: February 24, 2004, 11:12:25 AM »
uh kinda makes sense but to be honest i'm new to coding. i'm only at the point that i can see where things are occuring but not how to make them occur. don't really know the terms and their functions yet. could you elaborate pretty please

Columbia

  • Guest
stretch objects on specified layer help
« Reply #6 on: February 25, 2004, 01:03:20 PM »
Well then try this... I modified the whole code block but left in the old stuff only remarked out.  I was not able to test it because I don't have all of the child functions.  But the idea is the same.  You would use the while list to build your filter string, and then add that to an ssget statement within the STRETCH command.

I hope this clears a bit up for you...  If not let me know and I'll try to put it another way.

Code: [Select]

(defun c:SL
(/ enlay entlst ename olderr selset enum objlen dent layent layset lay pt1 pt2 ss ss1 ss2 en osm)
  (vl-load-com)
  (if (null myerr)(load "myerr"))
  (setq olderr *error* *error* myerr)
  (setq osm (getvar "osmode"))
  (if (null setvars)(load "setvars"))
  (setq syslst
(setvars '(("cmdecho" . 0) ("osmode" . 0) ("trimmode" . 1)) )
  )

;; The following section is not needed - because it is replaced by
;; the while loop I was talking about
;(setq dent(list(entsel"\nPICK AN ENTITY ON THE LAYER YOU WISH STRETCHED: ")))
;(setq dent(caar dent))
;(setq layent(entget dent))
;(setq layset(assoc 8 layent))
;(setq lay(cdr layset))
;(prompt "\n")
;(princ lay)
  (while (setq ent (entsel "\nSelect entity on layer...")) ;; <- here's the while loop!!
    (setq layer_string
      (if layer_string
        (strcat layer_string ","
          (vla-get-layer (vlax-ename->vla-object (car ent)))
        )
        (vla-get-layer (vlax-ename->vla-object (car ent)))
      )
    )
  )
;; The following is not needed at all - because the filtering
;; would be done by the layer_string and ssget at stretch time...
;  (setq pt1 (getpoint "\n1ST POINT OF STRETCH WINDOW..."))
;  (SETQ PT2 (GETCORNER PT1 "\n....2ND POINT "))
;  (PROMPT "\n<A>DD OR <R>EMOVE OBJECTS:\n")
;  (COMMAND "SELECT" "C" PT1 PT2 PAUSE)
;  (SETQ SS (SSGET "P"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;(setq objlen(sslength SS))
;(setq enum 0)
;(setq selset(ssadd))
;(repeat objlen
;(setq ename(ssname SS enum))
;(setq entlst(entget ename))
;(setq enlay(assoc 8 entlst))
;(setq enlay(cdr enlay))
;(if (= enlay lay)
;(ssadd ename selset))
;(setq enum(+ enum 1))
;)
;(SETQ SS selset)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  (SETQ SS1 (SSGET "C" PT1 PT2))
;  (SETQ SS2 (SSADD))
;  (WHILE (SETQ EN (SSNAME SS1 0))
;   (IF (NULL (SSMEMB EN SS))
;    (SSADD EN SS2)
;   )
;   (SSDEL EN SS1)
;  )
; (setvar "osmode" osm)
;  (IF (< 0 (SSLENGTH SS2))
;   (COMMAND "SELECT" SS2 ""
;    "STRETCH" "C" PT1 PT2 "R" "P" "")
;   (COMMAND "STRETCH" "C" PT1 PT2 "")
;  )
(princ "\nSelect objects to stretch by crossing-window or crossing-polygon...")
(command "._stretch" (ssget (list (cons 8 layer_string)))) ;;<- this is where the filtering is done.
  (setvars syslst)
  (setq *error* olderr)
  (princ)
)

(defun myerr (msg)
   (if (or (= msg "quit / exit abort")
           (= msg "Function cancelled"))
      (if (and ctl undo_err)   ; if undo_start used and returned value saved
         (undo_err ctl))       ; in ctl then undo everything done so far.
      (princ msg))
   (if (and setvars syslst) ; if usual system var handler and variable exist
      (setvars syslst))     ; then restore system vars
   (setq *error* OLDERR ctl nil)
   (princ)
)

(defun setvars (syslst / oldlst)
   (foreach dp syslst
      (setq oldlst (cons
         (cons (car dp) (getvar (car dp)))
         oldlst)))
   (foreach dp syslst
      (setvar (car dp) (cdr dp))
   )
   oldlst
)


(princ "\nEnter SL to stretch entities on a single layer.")
(princ)

ELOQUINTET

  • Guest
stretch objects on specified layer help
« Reply #7 on: February 25, 2004, 09:53:39 PM »
columbia i've first posted the altered code then i have posted the results i got. i opened a drawing , created 3 layers, then drew 3 c shapes which overlapped one another. then i started the command selecting 2 of the layers. the first thing i noticed was after i selected them it made me hit enter twice before allowing me to pick my window. after that it did exactly what i want stretching the 2 and filtering the third out. when i tried it again i only selected 1 layer. when i stretched only the original filtered out layer remained filtered thus the two layers stretched again when i only wanted 1 to. can you help me see the error because i can't pick it out. thanks




[/code](defun c:SLtest
   (/ enlay entlst ename olderr selset enum objlen dent layent layset lay pt1 pt2 ss ss1 ss2 en osm)
  (vl-load-com)
  (if (null myerr)(load "myerr"))
  (setq olderr *error* *error* myerr)
  (setq osm (getvar "osmode"))
  (if (null setvars)(load "setvars"))
  (setq syslst
      (setvars '(("cmdecho" . 0) ("osmode" . 0) ("trimmode" . 1)) )
  )
  (while (setq ent (entsel "\nSelect entity on layer..."))
    (setq layer_string
      (if layer_string
        (strcat layer_string ","
          (vla-get-layer (vlax-ename->vla-object (car ent)))
        )
        (vla-get-layer (vlax-ename->vla-object (car ent)))
      )
    )
  )
   (princ "\nSelect objects to stretch by crossing-window or crossing-polygon...")
   (command "._stretch" (ssget (list (cons 8 layer_string)))) ;;<- this is where the filtering is done.
  (setvars syslst)
  (setq *error* olderr)
  (princ)
)
(defun myerr (msg)
   (if (or (= msg "quit / exit abort")
           (= msg "Function cancelled"))
      (if (and ctl undo_err)   ; if undo_start used and returned value saved
         (undo_err ctl))       ; in ctl then undo everything done so far.
      (princ msg))
   (if (and setvars syslst) ; if usual system var handler and variable exist
      (setvars syslst))     ; then restore system vars
   (setq *error* OLDERR ctl nil)
   (princ)
)

(defun setvars (syslst / oldlst)
   (foreach dp syslst
      (setq oldlst (cons
         (cons (car dp) (getvar (car dp)))
         oldlst)))
   (foreach dp syslst
      (setvar (car dp) (cdr dp))
   )
   oldlst
)


(princ "\nEnter SL to stretch entities on a single layer.")
(princ)
Code: [Select]



Command: sltest
Select entity on layer...
Select entity on layer...
Select entity on layer...
Select objects to stretch by crossing-window or crossing-polygon...
Select objects: Specify opposite corner: 9 found
3 were filtered out.
Select objects:
Select objects:
Specify base point or displacement:
Specify second point of displacement or <use first point as displacement>:
Command:
SLTEST
Select entity on layer...
Select entity on layer...
Select objects to stretch by crossing-window or crossing-polygon...
Select objects: Specify opposite corner: 9 found
3 were filtered out.
Select objects:
Select objects:
Specify base point or displacement:
Specify second point of displacement or <use first point as displacement
Command:

Columbia

  • Guest
stretch objects on specified layer help
« Reply #8 on: February 26, 2004, 06:48:16 AM »
Dan,

Localize the variables "layer_string" and "ent" and that should take care of one of the problems.

As for the double enter, try modifying this line

Code: [Select]
(command "._stretch" (ssget (list (cons 8 layer_string))))

to read like this...

Code: [Select]

(command "._stretch" (ssget (list (cons 8 layer_string))) "")


Try that and let me know how it works...

ELOQUINTET

  • Guest
stretch objects on specified layer help
« Reply #9 on: February 26, 2004, 07:51:23 AM »
ok the double enter is corrected . i've heard the term localize variables but not sure how to do that? thanks for all your help

Columbia

  • Guest
stretch objects on specified layer help
« Reply #10 on: February 26, 2004, 12:22:50 PM »
localizing variables is a term that means ( in a very simplistic fashion - without getting into a lengthy dissertation on scope) the program will reset  the variables to 'nil' after program execution.  To do that you need to add them to the function header list.

Code: [Select]

(defun someFunction ( [arguments go here] / [local variables go here] )...)


So add "ent" and "layer_string" to the header list and you should be good to go.

ELOQUINTET

  • Guest
stretch objects on specified layer help
« Reply #11 on: February 26, 2004, 12:47:05 PM »
thanks for helping me along columbia it works great now appreciate the lesson. here's what i have:


Code: [Select]
(defun c:SL
(/ layer_string ent enlay entlst ename olderr selset enum objlen dent layent layset lay pt1 pt2 ss ss1 ss2 en osm)
(vl-load-com)
(if (null myerr)(load "myerr"))
(setq olderr *error* *error* myerr)
(setq osm (getvar "osmode"))
(if (null setvars)(load "setvars"))
(setq syslst
(setvars '(("cmdecho" . 0) ("osmode" . 0) ("trimmode" . 1)) )
)
(while (setq ent (entsel "\nSelect entity on layer..."))
(setq layer_string
(if layer_string
(strcat layer_string ","
(vla-get-layer (vlax-ename->vla-object (car ent)))
)
(vla-get-layer (vlax-ename->vla-object (car ent)))
)
)
)
(princ "\nSelect objects to stretch by crossing-window or crossing-polygon...")
(command "._stretch" (ssget (list (cons 8 layer_string))) "")  
(setvars syslst)
(setq *error* olderr)
(princ)
)
(defun myerr (msg)
(if (or (= msg "quit / exit abort")
(= msg "Function cancelled"))
(if (and ctl undo_err) ; if undo_start used and returned value saved
(undo_err ctl)) ; in ctl then undo everything done so far.
(princ msg))
(if (and setvars syslst) ; if usual system var handler and variable exist
(setvars syslst)) ; then restore system vars
(setq *error* OLDERR ctl nil)
(princ)
)

(defun setvars (syslst / oldlst)
(foreach dp syslst
(setq oldlst (cons
(cons (car dp) (getvar (car dp)))
oldlst)))
(foreach dp syslst
(setvar (car dp) (cdr dp))
)
oldlst
)


(princ)

3dwannab

  • Newt
  • Posts: 39
Re: stretch objects on specified layer help
« Reply #12 on: July 03, 2023, 06:58:24 PM »
My stab at it. Most (all) of the power in this, is LeeMacs LM:lst->str defun.

Code: [Select]
;;
;; Stretch by Layer(s)
;; Allows a selection set for layer selection and to stretch said layers
;; Written on 2023.07.03 by 3dwannab
;; Dependant LeeMac defun required 'LM:lst->str'
;;

(defun c:SLAY (/ LM:lst->str lay laylist laystr n ss1)

  ;; List to String  -  Lee Mac
  ;; Concatenates each string in a supplied list, separated by a given delimiter
  ;; lst - [lst] List of strings to concatenate
  ;; del - [str] Delimiter string to separate each item

  (defun LM:lst->str (lst del)
    (if (cdr lst)
      (strcat (car lst) del (LM:lst->str (cdr lst) del))
      (car lst)
    )
  )

  (prompt "\nSelect layer(s) you wish to stretch:")
  (setq ss1 (ssget "_:L"))

  (if ss1
    (progn

      (repeat (setq n (sslength ss1))
        (setq lay (cdr (assoc 8 (entget (ssname ss1 (setq n (1- n)))))))
        (if (not (member lay laylist)) (setq laylist (cons lay laylist)))
      ) ; repeat

      (setq laystr (LM:lst->str laylist ",")) ;; Converts the layer list to pass the ssget like: (ssget (list (cons 8 "Layer1,Layer2,etc")))

      (if ss1
        (progn
          (prompt "\nSelect object(s) you wish to stretch:")
          (command "._stretch" (ssget (list (cons 8 laystr))) "")
        ) ; progn
      ) ; if ss1 do command
    ) ; progn
  ) ; if ss1
) ; defun



; (c:SLAY) ;; Uncomment for testing
« Last Edit: July 03, 2023, 07:12:45 PM by 3dwannab »

ScottMC

  • Newt
  • Posts: 191
Re: stretch objects on specified layer help
« Reply #13 on: July 09, 2023, 05:42:38 PM »
--OOPS-- Removing the single filter..

Excellent 3dwannab and consider my mods for w/cp..
 .. thanks much to LeeMac too.

Code: [Select]
;;
;; Stretch by Layer(s)
;; Allows a selection set for layer selection and to stretch said layers
;; Written on 2023.07.03 by 3dwannab
;; Dependant LeeMac defun required 'LM:lst->str'
;; 

(defun c:lst (/ *error* LM:lst->str lay laylist laystr n ss1)

  (defun *error* ( msg )
    (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
    (if qaf (setvar 'qaflags qaf))
    (if msg (prompt msg))
    (setvar 'cmdecho 1)
    (setvar 'nomutt 0)

    (princ)
  )
  ;; List to String  -  Lee Mac
  ;; Concatenates each string in a supplied list, separated by a given delimiter
  ;; lst - [lst] List of strings to concatenate
  ;; del - [str] Delimiter string to separate each item

  (defun LM:lst->str (lst del)
    (if (cdr lst)
      (strcat (car lst) del (LM:lst->str (cdr lst) del))
      (car lst)
    )
  )

(setvar 'cmdecho 0)
(setvar 'nomutt 1)
  (princ "\n * Layer Filter Selection * \n Entity(s) on Layers to Stretch: ")
  (setq ss1 (ssget "_:L"))

  (if ss1
    (progn

      (repeat (setq n (sslength ss1))
        (setq lay (cdr (assoc 8 (entget (ssname ss1 (setq n (1- n)))))))
        (if (not (member lay laylist)) (setq laylist (cons lay laylist)))
      ) ; repeat

      (setq laystr (LM:lst->str laylist ",")) ;; Converts the layer list to pass the ssget like: (ssget (list (cons 8 "Layer1,Layer2,etc")))

    (if ss1
            (progn
              (princ " Select by Crossing-Window or Crossing-Polygon to Stretch: <filtered>")
              (command "._stretch" (ssget (list (cons 8 laystr))) "") ;; removed.. [color=red]added :S for single window!![/color]
            ) ; progn
         ) ; if ss1 do command
        ) ; progn
      ) ; if ss1
    (setvar 'cmdecho 1)
    (setvar 'nomutt 0)
               (princ)
) ; defun



; (c:SLAY) ;; Uncomment for testing
« Last Edit: July 10, 2023, 08:43:00 PM by ScottMC »

3dwannab

  • Newt
  • Posts: 39
Re: stretch objects on specified layer help
« Reply #14 on: July 10, 2023, 05:58:14 PM »
Hi Scott. FYI, With yours you can't do a lasso for the stretch. See GIF.