Jump to content

Offset object to different elevation and on different layer


KRBeckman

Recommended Posts

Anybody know how I'd go about writing a lisp to offset an object (line, polyline, or arc), to a different elevation (0.00 to 29.00), and onto the current layer. I know the offset command has the layer part built in, I just wouldn't know how to change the elevation.

 

Thanks in advance for your help.

Link to comment
Share on other sites

  • Replies 26
  • Created
  • Last Reply

Top Posters In This Topic

  • alanjt

    12

  • KRBeckman

    11

  • Lee Mac

    3

  • BIGAL

    1

Top Posters In This Topic

Once the object is offset, you set the newly offset curve with (entlast). From there, you can change the elevation.

You can change the elevation with VLA, Entmod or the Change command, if you want the 'easy' way.

Link to comment
Share on other sites

Awesome, thanks

No problem.

 

Here's a crude example (will fail if selected object is on locked layer)...

 

(defun c:OTE (/ *error* Cmd Elev Obj Pnt)
 ;; Offset selected object(s) to current layer and change elevation
 ;; Alan J. Thompson, 03.24.10
 (vl-load-com)

 (setq *error* (lambda (m) (and Cmd (setvar 'cmdecho Cmd)) (princ (strcat "\nError: " m))))

 (setq Cmd (getvar 'cmdecho))
 (setvar 'cmdecho 0)

 (and (eq -1 (getvar 'offsetdist)) (setvar 'offsetdist 1))

 (and (setvar
        'offsetdist
        (cond ((getdist (strcat "\nSpecify offset distance <" (rtos (getvar 'offsetdist)) ">: ")))
              ((getvar 'offsetdist))
        ) ;_ cond
      ) ;_ setvar
      (or (setq Elev (getreal "\nSpecify new elevation for offset object: ")) T)
      (while (setq Obj (car (entsel "\nSelect object to offset: ")))
        (if (vl-position (cdr (assoc 0 (entget Obj))) '("ARC" "CIRCLE" "LINE" "LWPOLYLINE"))
          (if (setq Pnt (getpoint "\nSpecify point on side to offset: "))
            (and (vl-cmdf "_.offset" "" Obj "_non" Pnt "")
                 (not (vla-put-layer (vlax-ename->vla-object (entlast)) (getvar 'clayer)))
                 Elev
                 (vl-cmdf "_.change" (entlast) "" "_p" "_e" Elev "")
            ) ;_ and
          ) ;_ if
          (princ "\nInvalid object!")
        ) ;_ if
      ) ;_ while
 ) ;_ and
 (and Cmd (setvar 'cmdecho Cmd))
 (princ)
) ;_ defun

Link to comment
Share on other sites

No problem.

 

Here's a crude example (will fail if selected object is on locked layer)...

 

(defun c:OTE (/ *error* Cmd Elev Obj Pnt)
 ;; Offset selected object(s) to current layer and change elevation
 ;; Alan J. Thompson, 03.24.10
 (vl-load-com)

 (setq *error* (lambda (m) (and Cmd (setvar 'cmdecho Cmd)) (princ (strcat "\nError: " m))))

 (setq Cmd (getvar 'cmdecho))
 (setvar 'cmdecho 0)

 (and (eq -1 (getvar 'offsetdist)) (setvar 'offsetdist 1))

 (and (setvar
        'offsetdist
        (cond ((getdist (strcat "\nSpecify offset distance <" (rtos (getvar 'offsetdist)) ">: ")))
              ((getvar 'offsetdist))
        ) ;_ cond
      ) ;_ setvar
      (or (setq Elev (getreal "\nSpecify new elevation for offset object: ")) T)
      (while (setq Obj (car (entsel "\nSelect object to offset: ")))
        (if (vl-position (cdr (assoc 0 (entget Obj))) '("ARC" "CIRCLE" "LINE" "LWPOLYLINE"))
          (if (setq Pnt (getpoint "\nSpecify point on side to offset: "))
            (and (vl-cmdf "_.offset" "" Obj "_non" Pnt "")
                 (not (vla-put-layer (vlax-ename->vla-object (entlast)) (getvar 'clayer)))
                 Elev
                 (vl-cmdf "_.change" (entlast) "" "_p" "_e" Elev "")
            ) ;_ and
          ) ;_ if
          (princ "\nInvalid object!")
        ) ;_ if
      ) ;_ while
 ) ;_ and
 (and Cmd (setvar 'cmdecho Cmd))
 (princ)
) ;_ defun

 

 

Works like a charm man, and I don't lock layers so that shouldn't be a problem.

Link to comment
Share on other sites

I changed it up a little to add in a default value and now it also saves the elevation from the previous running:

 

(defun c:of (/ *error* Cmd Obj Pnt)
 ;; Offset selected object(s) to current layer and change elevation
 ;; Alan J. Thompson, 03.24.10
 ;; Edited by Kyle Beckman, 03.25.10
 (vl-load-com)
 (setq *error* (lambda (m) (and Cmd (setvar 'cmdecho Cmd)) (princ (strcat "\nError: " m))))
 (setq Cmd (getvar 'cmdecho))
 (setvar 'cmdecho 0)
 (and (eq -1 (getvar 'offsetdist)) (setvar 'offsetdist 0.118))
 (if (not prr_of) (setq Elev 29))
 (setq Elev_def Elev)
 (setq Elev_pmt (strcat "\nSpecify new elevation for offset object <" (rtos Elev) ">: "))
 (and (setvar
        'offsetdist
        (cond ((getdist (strcat "\nSpecify offset distance <" (rtos (getvar 'offsetdist)) ">: ")))
              ((getvar 'offsetdist))
        ) ;_ cond
      ) ;_ setvar
      (or (setq Elev (getreal Elev_pmt))
   (setq Elev (if (not Elev) Elev_def Elev)))
      (while (setq Obj (car (entsel "\nSelect object to offset: ")))
        (if (vl-position (cdr (assoc 0 (entget Obj))) '("ARC" "CIRCLE" "LINE" "LWPOLYLINE"))
          (if (setq Pnt (getpoint "\nSpecify point on side to offset: "))
            (and (vl-cmdf "_.offset" "" Obj "_non" Pnt "")
                 (not (vla-put-layer (vlax-ename->vla-object (entlast)) (getvar 'clayer)))
                 Elev
                 (vl-cmdf "_.change" (entlast) "" "_p" "_e" Elev "")
            ) ;_ and
          ) ;_ if
          (princ "\nInvalid object!")
        ) ;_ if
      ) ;_ while
 ) ;_ and
 (setq prr_of (if (= prr_of nil) 1 (+ prr_of 1)))

 (and Cmd (setvar 'cmdecho Cmd))
 (princ)
) ;_ defun

Link to comment
Share on other sites

I changed it up a little to add in a default value and now it also saves the elevation from the previous running:

 

I do have one request, that if you modify code I post, please state in the routine that it was modified by you.

 

I'm a little confused about the changes. You've created several new variables which I don't understand. prr_of has no purpose as I can see. What're you trying to accomplish?

Link to comment
Share on other sites

Gotcha, I edited the post and from now on I will do that.

 

prr_of:

 

In all the longer lisps I write I like to add a counter of how many times it has been ran, which isn't really neccessary, but in this case I use it to determine if the lisp has been previously ran, and if it hasn't set Elev to 29, if it has been ran, leave it at whatever it is. And just to stay consistant I always name this variable prr_* where * is the text that needs to be entered into the command prompt.

 

Elev_pmt:

 

This is just a string of the prompt for Elev, not neccessary, just how I like to do it.

 

Elev_def:

 

Saves the value of Elev before the prompt that way a blank entry can be used. I'm sure there is an easier way to do it, I just did it this way the first time I wrote a lisp and never looked into it. If you have a better way i'm all ears.

 

Hope this helps.

Link to comment
Share on other sites

Gotcha, I edited the post and from now on I will do that.

 

prr_of:

 

In all the longer lisps I write I like to add a counter of how many times it has been ran, which isn't really neccessary, but in this case I use it to determine if the lisp has been previously ran, and if it hasn't set Elev to 29, if it has been ran, leave it at whatever it is. And just to stay consistant I always name this variable prr_* where * is the text that needs to be entered into the command prompt.

 

Elev_pmt:

 

This is just a string of the prompt for Elev, not neccessary, just how I like to do it.

 

Elev_def:

 

Saves the value of Elev before the prompt that way a blank entry can be used. I'm sure there is an easier way to do it, I just did it this way the first time I wrote a lisp and never looked into it. If you have a better way i'm all ears.

 

Hope this helps.

 

Thanks.

Do you tally these prr_* before you close out of a drawing?

 

I think this will do the same thing, just a little differently. Always remember to localize your variables (unless they're supposed to be global). When using global variables, I would always add something to them to look a little different and be specific to the routine. You don't want another routine trying to use the Elev variable.

 

Oh yeah, avoid assigning integers where you want a real. [use 29. or 29.0 instead of 29]

 

(defun c:of (/ *error* Cmd Obj Pnt)
 (vl-load-com)
 (setq *error* (lambda (m) (and Cmd (setvar 'cmdecho Cmd)) (princ (strcat "\nError: " m))))
 (setq Cmd (getvar 'cmdecho))
 (setvar 'cmdecho 0)
 (and (eq -1 (getvar 'offsetdist)) (setvar 'offsetdist 0.118))

 (or *of:Elev* (setq *of:Elev* 29.))

 (and (setvar
        'offsetdist
        (cond ((getdist (strcat "\nSpecify offset distance <" (rtos (getvar 'offsetdist)) ">: ")))
              ((getvar 'offsetdist))
        ) ;_ cond
      ) ;_ setvar

      (setq
        *of:Elev* (cond
                    ((getreal
                       (strcat "\nSpecify new elevation for offset object <" (rtos *of:Elev*) ">: ")
                     ) ;_ getreal
                    )
                    (*of:Elev*)
                  ) ;_ cond
      ) ;_ setq

      (while (setq Obj (car (entsel "\nSelect object to offset: ")))
        (if (vl-position (cdr (assoc 0 (entget Obj))) '("ARC" "CIRCLE" "LINE" "LWPOLYLINE"))
          (if (setq Pnt (getpoint "\nSpecify point on side to offset: "))
            (and (vl-cmdf "_.offset" "" Obj "_non" Pnt "")
                 (not (vla-put-layer (vlax-ename->vla-object (entlast)) (getvar 'clayer)))
                 (vl-cmdf "_.change" (entlast) "" "_p" "_e" *of:Elev* "")
            ) ;_ and
          ) ;_ if
          (princ "\nInvalid object!")
        ) ;_ if
      ) ;_ while
 ) ;_ and

 (setq prr_off (if prr_off
                 (1+ prr_off)
                 1
               ) ;_ if
 ) ;_ setq

 (and Cmd (setvar 'cmdecho Cmd))
 (princ)
) ;_ defun

Link to comment
Share on other sites

You mind explaining the logic of how this works???

 

(setq
        *of:Elev* (cond
                    ((getreal
                       (strcat "\nSpecify new elevation for offset object <" (rtos *of:Elev*) ">: ")
                     ) ;_ getreal
                    )
                    (*of:Elev*)
                  ) ;_ cond
      ) ;_ setq

 

I think I get what it does, but I can't figure out how it does it.

Link to comment
Share on other sites

You mind explaining the logic of how this works:?

 

(setq
        *of:Elev* (cond
                    ((getreal
                       (strcat "\nSpecify new elevation for offset object <" (rtos *of:Elev*) ">: ")
                     ) ;_ getreal
                    )
                    (*of:Elev*)
                  ) ;_ cond
      ) ;_ setq

I think I get what it does, but I can't figure out how it does it.

 

 

In the condition, if the first option cannot be filled (returns nil) it will go to the next. In this situation, it's just the variable itself. This is just a way to save you from having two variables when you only need the one.

 

Same as how I set the offsetdist. I didn't want to create an unneeded value stored in a variable.

 

  (and (setvar
        'offsetdist
        (cond ((getdist (strcat "\nSpecify offset distance <" (rtos (getvar 'offsetdist)) ">: ")))
              ((getvar 'offsetdist))
        ) ;_ cond
      ) ;_ setvar

Link to comment
Share on other sites

Ah, make sence... One other question if you don't mind....

 

In this code:

 

(and (setvar
        'offsetdist
        (cond ((getdist (strcat "\nSpecify offset distance <" (rtos (getvar 'offsetdist)) ">: ")))
              ((getvar 'offsetdist))
        ) ;_ cond
      ) ;_ setvar

      (setq
        *of:Elev* (cond
                    ((getreal
                       (strcat "\nSpecify new elevation for offset object <" (rtos *of:Elev*) ">: ")
                     ) ;_ getreal
                    )
                    (*of:Elev*)
                  ) ;_ cond
      ) ;_ setq

      (while (setq Obj (car (entsel "\nSelect object to offset: ")))
        (if (vl-position (cdr (assoc 0 (entget Obj))) '("ARC" "CIRCLE" "LINE" "LWPOLYLINE"))
          (if (setq Pnt (getpoint "\nSpecify point on side to offset: "))
            (and (vl-cmdf "_.offset" "" Obj "_non" Pnt "")
                 (not (vla-put-layer (vlax-ename->vla-object (entlast)) (getvar 'clayer)))
                 (vl-cmdf "_.change" (entlast) "" "_p" "_e" *of:Elev* "")
            ) ;_ and
          ) ;_ if
          (princ "\nInvalid object!")
        ) ;_ if
      ) ;_ while
 ) ;_ and

 

What is the purpose of putting all this inside an "AND" function?

Link to comment
Share on other sites

What is the purpose of putting all this inside an "AND" function?

 

So the routine will not continue if all values have not been filled.

For example:

 

(and (setq r (getreal "\nNumber (with and): "))
    (princ (rtos r))
)

(progn (setq r (getreal "\nNumber (without and): "))
      (princ (rtos r))
)

 

Number (with and):
nil

Command:


Number (without and):

Error: bad argument type: numberp: nil

Link to comment
Share on other sites

Do you tally these prr_* before you close out of a drawing?

 

Not everytime, but I do use the capability everyonce in a while.

 

 

Oh yeah, avoid assigning integers where you want a real. [use 29. or 29.0 instead of 29]

 

Good call.

 

Is there any reason why you use COND functions here instead of IF functions?

Link to comment
Share on other sites

Is there any reason why you use COND functions here instead of IF functions?

 

Because I want a return value without having to assign values to another variable.

For example:

 

(cond ((getreal "\nNumber: "))

(2.))

 

If the getreal statement is nil, it will return 2, if it's true, it will return the value entered.

 

(if (getreal "\nNumber: ") ;

Link to comment
Share on other sites

(if (getreal "\nNumber: ") ;

 

Right but couldn't you use:

 

(if (getreal "\nNumber <2>: ") 2)

 

That way it will accept the user inputted number, or use the default "2" if enter is pressed.

Link to comment
Share on other sites

Right but couldn't you use:

 

(if (getreal "\nNumber <2>: ") 2)

That way it will accept the user inputted number, or use the default "2" if enter is pressed.

That will only return 2 if getreal is T.

 

Command: (if (getreal "\nNumber <2>: ") 2)

Number <2>: 5
2

 

 

Command: (if (getreal "\nNumber <2>: ") 2)

Number <2>:
nil

 

If only checks if a statement is T or nil. I used cond so it would return a variable, regardless of the statement being nil or T.

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