Jump to content

Offset Polyline Help


BrianTFC

Recommended Posts

Hi All,

 

I have the wonderful Lisp routine that mfuccaro wrote back in 2003 called Offset Polylines "POF" for short. like I've said before in my other threads I'm just learning how to write and modify Lisp routines, I've manage to modify this routine to offset to the current layer but i can't figure out how to get it to remember the last offset distance. Can anyone help me please.

 

thanks,

Brian

 

 

;|    OFFSET POLYLINES
mfuccaro@hotmail.com    September 2003
|;
(defun c:pof( / plines    ; selection set of polylines
           ext    ; extrnal point
            dist    ; distance to offset
            poly    ; a polyline from plines
            plist    ; the list of poly
            del    ; polyline to delete
            int    ; internal point
            i)
 (command "undo" "begin")
 (princ "select polylines")
 (setq plines (ssget)
   i 0
   ext (getvar "limmax")
   dist (getdist "distance "))
 (repeat (sslength plines)
   (setq poly (ssname plines i))
   (setq plist (entget poly))
   (command "offset" dist poly ext "")
   (setq del (entlast)
     int (polar
       (cdr (assoc 10 (entget del)))
            (angle
              (cdr (assoc 10 (entget del)))
              (cdr (assoc 10 plist)))
            (* 2 (distance (cdr (assoc 10 plist))
                   (cdr (assoc 10 (entget del)))))))
   (command "offset" dist poly int "")
    (command "_.change" (entlast) "" "_p" "_la" (getvar 'clayer) "")
  (entdel del)
   (setq i (1+ i)))
 (command "undo" "end")
 (princ)
 )

Link to comment
Share on other sites

Basically this is the same as for any other "default" input. You need to save the distance into a global variable, or some other place which doesn't get cleared after the routine completes. Then to show the distance you change the message in the getdist to something like: (strcat "distance : ") The the less-than & greater-than is a convention and doesn't actually mean much other than showing the user that this is the default.

 

Next you need to check if the distance input was a new distance, or if the user just pressed Enter/Space. On the getdist function a nill is returned if no distance is input. So:

(if (not *saved-dist*) (setq *saved-dist* 0.0)) ;Initialize the default distance to 0 if it doesn't exist

(if (setq dist (getdist (strcat "distance <" (rtos *saved-dist*) ">: ")))
 (setq *saved-dist* dist) ;A new distance was given, so save it into the global var
 (setq dist *saved-dist*) ;Enter/space pressed, so retrieve the global var
)

Continue as normal, since the dist variable now holds whatever the user wanted (either the new distance or the value of the default).

 

Note I use the lisp convention of prefixing & suffixing asterisks (*) onto the global variable's name. That's just a convention & not needed, but it is considered good practise to differentiate such variables.

 

Also note this would only make a default per DWG per session. To have a default over multiple DWG's per session or to have a default even over multiple sessions you'd need to save the global value to something else (like a file, the black-board, user sysvar, or registry).

Link to comment
Share on other sites

One solution is to not use a global variable to store the offset distance - will be preserved between runs. Just take care to don't reuse that name in other routine.

 

;|    OFFSET POLYLINES
[email="mfuccaro@hotmail.com"]mfuccaro@hotmail.com[/email]    September 2003
|;
(defun c:pof( / plines    ; selection set of polylines
           ext    ; extrnal point
            dist    ; distance to offset
            poly    ; a polyline from plines
            plist    ; the list of poly
            del    ; polyline to delete
            int    ; internal point
            i)
 (command "undo" "begin")
 (princ "select polylines")
 (setq plines (ssget)
   i 0
   ext (getvar "limmax")
   dist (getdist [color=blue](strcat "distance <" (if olddist
                                         (rtos olddist)   ;use old value as default
                                          "") ">")[/color])) 
[color=blue]  (if (not dist) (setq dist olddist))                      ;reuse old distance if user press <Enter>
[/color]  (repeat (sslength plines)
   (setq poly (ssname plines i))
   (setq plist (entget poly))
   (command "offset" dist poly ext "")
   (setq del (entlast)
     int (polar
       (cdr (assoc 10 (entget del)))
            (angle
              (cdr (assoc 10 (entget del)))
              (cdr (assoc 10 plist)))
            (* 2 (distance (cdr (assoc 10 plist))
                   (cdr (assoc 10 (entget del)))))))
   (command "offset" dist poly int "")
    (command "_.change" (entlast) "" "_p" "_la" (getvar 'clayer) "")
  (entdel del)
   (setq i (1+ i)))
 (command "undo" "end")
[color=blue]  (setq olddist dist)                                      ;preserve current distance for next run
[/color]  (princ)
 )

Regards,

Mircea

Edited by MSasu
fixed statement
Link to comment
Share on other sites

or

(setq plines (ssget)
   i 0
   ext (getvar "limmax")
   dist [color=blue][b](cond
         ((getdist
            (strcat
              "\nEnter Distance [Enter to accept: <"
              (rtos (setq dist (getvar 'Offsetdist)) 2 2)
              ">: "
              )
            )
          )
         (dist)
         )[/b][/color])

 

As posted on AUGI

Link to comment
Share on other sites

@pBe: I really like this solution; I will use this from now on my code. Thank you for sharing it!

 

Regards,

Mircea

 

Make it so Mircea, After all, thats what this forum is all about [sharing] :)

Link to comment
Share on other sites

One solution is to not use a global variable to store the offset distance - will be preserved between runs. Just take care to don't reuse that name in other routine.
Mircea, your code in post #3 is actually using a global variable. The olddist is global, it's just not indicated as such by the asterisk convention. As I've stated, the asterisk is simply a convention, it's not needed.

 

But, IMO pBe's solution is the most effective for this scenario as it uses the offset command's built-in default. Not to mention it's the most succinct :thumbsup: It's just that the getvar idea would only work in some instances, i.e. where acad has a built-in default which is saved as a sysvar. Otherwise you're stuck with using a global or some other variable (e.g. as ldata in the drawing to be persistend for that DWG even over separate sessions; or using vl-bb-set & vl-bb-get to have a default across all open DWG's in the current session; or a file/registry to have a persistent default across all DWG's and all sessions.

 

It all depends on what you want to achieve. Probably pBe's code is perfect for this case, but obviously it might need something else in another case. Though the global var default could easily be implemented in a similar cond statement to pBe's code. And actually I'd like to revise my original one thus as well:

(setq dist ((lambda (def / d)
             (cond
               ((setq d (getdist (strcat "Enter distance <" (rtos def) ">: ")))
                (setq *saved-dist* d)
               )
               (def)
             )
            )
            (if *saved-dist* *saved-dist* (setq *saved-dist* 0.))
          )
)

Not that is needed for this, just to show it is possible to use the same method even on a global var.

Link to comment
Share on other sites

@Mircea

 

sometimes i use.

USERS1-5

USERR1-5

USERI1-5

 

 
(setq dist (cond
                ((getdist
                       (strcat
                             "\nEnter Distance [Enter to accept: <"
                             (rtos (setq dist [color=blue][b](getvar 'userr1))[/b][/color] 2 2)
                             ">: "
                             )
                       )
                 )
                (dist)
                ))
[color=blue][b](setvar 'userr1 dist)[/b][/color]

 

It all depends on the usage really.

if i am to use "GLOBAL" [literally] ----- > vl-propagate

 

(vl-propagate 'dist)

 

Hope this helps

Link to comment
Share on other sites

@irneb: Thank you for your correction. You are right, that "not" should not be there. Sorry for inconvenience.

 

One solution is to not use a global variable to store the offset distance - will be preserved between runs. Just take care to don't reuse that name in other routine.

 

Regards,

Mircea

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...