Jump to content

Recommended Posts

Posted

In the code below, it allows you to offset an object on both sides per a specified or picked distance. Can anyone help me adjust so that you can put the total distance offset? In other words, I have a steel beam that I need to visually see the edge of flanges. Sometimes they are odd sizes and, albeit not that hard, I don't want to do the math do divide "15-5/8", for example. Call it laziness or just simply looking to go faster? Thanks for the help. Love this site.

 

-Nobull

 

P.S.

Not as important, but how do I default to deleting the centerline?

 

(vl-load-com)
(defun c:OO () (c:OffsetPlus))
(defun c:OffsetPlus (/ *error* _OffsetPlus:Settings _OffsetPlus:Distance
                    sel dist v acDoc
                   )
 (defun *error* (msg)
   (if acDoc
     (vla-endundomark acDoc)
   )
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
   )
   (princ)
 )
 (defun _OffsetPlus:Settings (/ erase)    
   (initget "No Yes")
   (or (setq erase
              (getkword
                (strcat "\nErase selection [No/Yes]"
                        (if *OffsetPlus_Erase*
                          " <Yes>: "
                          ": "
                        )
                )
              )
       )
       (setq erase *OffsetPlus_Erase*)
   )
   (setq *OffsetPlus_Erase*
          (if (= "No" erase)
            nil
            T
          )
   )
   (c:OffsetPlus)
 )
 (defun _OffsetPlus:Distance (sel / dist)
   (not (initget (+ 32 128)))
   (or (setq dist
              (getdist
                (cadr sel)
                (strcat "\nSpecify offset distance"
                        (if *OffsetPlus_Distance*
                          (strcat " <" (rtos *OffsetPlus_Distance*) ">: ")
                          ": "
                        )
                )
              )
       )
       (setq dist *OffsetPlus_Distance*)
   )
   (setq *OffsetPlus_Distance* dist)
 )
 (if
   (and
     (or
       (setq sel
              (entsel "\nSelect object to offset, <Enter> for Settings: "
              )
       )
       (_OffsetPlus:Settings)
     )
     (_OffsetPlus:Distance sel) 
     (setq v (vlax-ename->vla-object (car sel)))
   )
    (progn
      (vla-startundomark
        (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
      )
      (foreach d (list (abs *OffsetPlus_Distance*)
                       (* -1.0 *OffsetPlus_Distance*)
                 )
        (vla-offset v d)
      )
      (if *OffsetPlus_Erase*
        (vla-delete v)
        (progn
          (if (not (tblsearch "ltype" "center"))
            (vla-load (vla-get-linetypes acDoc) "center" "ACAD.LIN")
          )
          (vla-put-linetype v "center")
        )
      )
    )
 )
 (*error* nil)
)
** Edit to add - I've also included 'undo' functionality, FWIW.
HTH 

Posted

Dear Nobull84

 

 

For the dividing by 2 issue, a simple modification could be made to automatically divide the input by 2, but the thing is that the offset input accept both a distance and a point picking. That would mean that if you would pick a point 10 inches away from original entity, the offset would be of 5. Keyboard input distance would have to be divided by 2, but not distance by picking.

I thought I was getting somewhere, but as I managed to get that behavior I started to get "** Error: bad argument type: numberp: nil **" by hitting enter (entering dynamic offered value) instead of giving numeric input. Sorry I could not be of any help.

 

 

On the (unfortunately) less important point, I think I can help.

 

If you want to erase by default, Heres the thing.

 

 

*OffsetPlus_Erase* is defined by the variable erase, who is setted by the initget with a "Yes" or "No" value

(defun _OffsetPlus:Settings (/ erase)    
   (initget "No Yes")
   (or (setq erase ; [color=seagreen]Here you set erase var to "Yes" or "No", limited by the initget[/color]
              (getkword
                (strcat "\nErase selection [No/Yes]"
                        (if *OffsetPlus_Erase*
                          " <Yes>: "
                          ": "
                        )
                )
              )
       )
       (setq erase *OffsetPlus_Erase*)
   )
   (setq *OffsetPlus_Erase*;[color=seagreen] and here you set *OffsetPlus_Erase*[/color]
          (if (= "No" erase); [color=seagreen]if erase in "No", *OffsetPlus_Erase* get the value T[/color]
            nil
            T
          )

After that the code check the value of *OffsetPlus_Erase*. If it has a value, then it erases the starting line. If it don't exist, it changes it to a centerline. (and it only exists if you enter the subfunction settings, if you select erase )

  (if *OffsetPlus_Erase*
        (vla-delete v)

You can invert things like following. Instead of *OffsetPlus_Erase*, we will use *OffsetPlus_KEEP*, and invert the final checkup. That way If the var *OffsetPlus_KEEP* it T ( If you set erase to , *OffsetPlus_KEEP* will be true), the starting entity will be kept. but if you don't change settings, since *OffsetPlus_KEEP* wont exist and will be nil, the default behavior will erase the starting entity. (backup original lisp tho, just in case you get unwanted behaviors, you will be able to switch back. I did some test and it seems to work fine)

 

 

(vl-load-com)
(defun c:OO () (c:OffsetPlus))
(defun c:OffsetPlus (/ *error* _OffsetPlus:Settings _OffsetPlus:Distance
                    sel dist v acDoc
                   )
 (defun *error* (msg)
   (if acDoc
     (vla-endundomark acDoc)
   )
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
   )
   (princ)
 )
 (defun _OffsetPlus:Settings (/ erase)    
   (initget "No Yes")
   (or (setq erase
              (getkword
                (strcat "\nErase selection [No/Yes]"
                        (if *OffsetPlus_KEEP*
                          " <Yes>: "
                          ": "
                        )
                )
              )
       )
       (setq erase *OffsetPlus_KEEP*)
   )
   (setq *OffsetPlus_KEEP*
          (if (= "No" erase)
            T
            nil
          )
   )
   (c:OffsetPlus)
 )
 (defun _OffsetPlus:Distance (sel / dist)
   (not (initget (+ 32 128)))
   (or (setq dist
               (getdist
                (cadr sel)
                (strcat "\nSpecify offset distance"
                        (if *OffsetPlus_Distance*
                          (strcat " <" (rtos *OffsetPlus_Distance*) ">: ")
                          ": "
                        )
                )
              )
       )
       (setq dist *OffsetPlus_Distance*)
   )
   (setq *OffsetPlus_Distance* dist)
 )
 (if
   (and
     (or
       (setq sel
              (entsel "\nSelect object to offset, <Enter> for Settings: "
              )
       )
       (_OffsetPlus:Settings)
     )
     (_OffsetPlus:Distance sel) 
     (setq v (vlax-ename->vla-object (car sel)))
   )
    (progn
      (vla-startundomark
        (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
      )
      (foreach d (list (abs *OffsetPlus_Distance*)
                       (* -1.0 *OffsetPlus_Distance*)
                 )
        (vla-offset v d)
      )
      (if (not *OffsetPlus_KEEP*)
        (vla-delete v)
        (progn
          (if (not (tblsearch "ltype" "center"))
            (vla-load (vla-get-linetypes acDoc) "center" "ACAD.LIN")
          )
          (vla-put-linetype v "center")
        )
      )
    )
 )
 (*error* nil)
)

Not totally the result you hoped for, but at least you wont have to go into settings to remove the center line.

 

 

Week-end-ô-clock!

Cheers!

Jef!

Posted

Change this :

(foreach d (list (abs *OffsetPlus_Distance*) (* -1.0 *OffsetPlus_Distance*) )          
 (vla-offset v d)
)

To this:

(foreach d (list (abs (* 0.5 *OffsetPlus_Distance*)) (* -0.5 *OffsetPlus_Distance*) )          
 (vla-offset v d)
)

Posted

I have it on my do list to make a offset pline that just keeps asking for offsets +ve is right, negative is left plus width of pline 3 -3 two plines 3 -2.3 -4 3.5 -2.5 5 etc will try to do this week and will post.

Posted

I just got to work this morning and have been using the altered code you all have helped. It's going near perfect, but one tiny hiccup maybe someone could explain? When using the lisp for the first time in a drawing file, upon completed the action in simply deletes the line I am offsetting with a response of "nil" in the command bar. This only happens on the first use and then works flawlessly afterward. Here's what I'm using:

 

(vl-load-com)
(defun c:OO () (c:OffsetPlus))
(defun c:OffsetPlus (/ *error* _OffsetPlus:Settings _OffsetPlus:Distance
                    sel dist v acDoc
                   )
 (defun *error* (msg)
   (if acDoc
     (vla-endundomark acDoc)
   )
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
   )
   (princ)
 )
 (defun _OffsetPlus:Settings (/ erase)    
   (initget "No Yes")
   (or (setq erase
              (getkword
                (strcat "\nErase selection [No/Yes]"
                        (if *OffsetPlus_KEEP*
                          " <Yes>: "
                          ": "
                        )
                )
              )
       )
       (setq erase *OffsetPlus_KEEP*)
   )
   (setq *OffsetPlus_KEEP*
          (if (= "No" erase)
            T
            nil
          )
   )
   (c:OffsetPlus)
 )
 (defun _OffsetPlus:Distance (sel / dist)
   (not (initget (+ 32 128)))
   (or (setq dist
               (getdist
                (cadr sel)
                (strcat "\nSpecify offset distance"
                        (if *OffsetPlus_Distance*
                          (strcat " <" (rtos *OffsetPlus_Distance*) ">: ")
                          ": "
                        )
                )
              )
       )
       (setq dist *OffsetPlus_Distance*)
   )
   (setq *OffsetPlus_Distance* dist)
 )
 (if
   (and
     (or
       (setq sel
              (entsel "\nSelect object to offset, <Enter> for Settings: "
              )
       )
       (_OffsetPlus:Settings)
     )
     (_OffsetPlus:Distance sel) 
     (setq v (vlax-ename->vla-object (car sel)))
   )
    (progn
      (vla-startundomark
        (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
      )
      (vl-load-com)
(defun c:OO () (c:OffsetPlus))
(defun c:OffsetPlus (/ *error* _OffsetPlus:Settings _OffsetPlus:Distance
                    sel dist v acDoc
                   )
 (defun *error* (msg)
   (if acDoc
     (vla-endundomark acDoc)
   )
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
   )
   (princ)
 )
 (defun _OffsetPlus:Settings (/ erase)    
   (initget "No Yes")
   (or (setq erase
              (getkword
                (strcat "\nErase selection [No/Yes]"
                        (if *OffsetPlus_KEEP*
                          " <Yes>: "
                          ": "
                        )
                )
              )
       )
       (setq erase *OffsetPlus_KEEP*)
   )
   (setq *OffsetPlus_KEEP*
          (if (= "No" erase)
            T
            nil
          )
   )
   (c:OffsetPlus)
 )
 (defun _OffsetPlus:Distance (sel / dist)
   (not (initget (+ 32 128)))
   (or (setq dist
               (getdist
                (cadr sel)
                (strcat "\nSpecify offset distance"
                        (if *OffsetPlus_Distance*
                          (strcat " <" (rtos *OffsetPlus_Distance*) ">: ")
                          ": "
                        )
                )
              )
       )
       (setq dist *OffsetPlus_Distance*)
   )
   (setq *OffsetPlus_Distance* dist)
 )
 (if
   (and
     (or
       (setq sel
              (entsel "\nSelect object to offset, <Enter> for Settings: "
              )
       )
       (_OffsetPlus:Settings)
     )
     (_OffsetPlus:Distance sel) 
     (setq v (vlax-ename->vla-object (car sel)))
   )
    (progn
      (vla-startundomark
        (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
      )
      (foreach d (list (abs (* 0.5 *OffsetPlus_Distance*)) (* -0.5 *OffsetPlus_Distance*) )  
        (vla-offset v d)
      )
      (if (not *OffsetPlus_KEEP*)
        (vla-delete v)
        (progn
          (if (not (tblsearch "ltype" "center"))
            (vla-load (vla-get-linetypes acDoc) "center" "ACAD.LIN")
          )
          (vla-put-linetype v "center")
        )
      )
    )
 )
 (*error* nil)
)
Not totally the result you hoped for, but at least you wont have to go into settings to remove the center line.

Week-end-ô-clock!
                       (* -1.0 *OffsetPlus_Distance*)
                 )
        (vla-offset v d)
      )
      (if (not *OffsetPlus_KEEP*)
        (vla-delete v)
        (progn
          (if (not (tblsearch "ltype" "center"))
            (vla-load (vla-get-linetypes acDoc) "center" "ACAD.LIN")
          )
          (vla-put-linetype v "center")
        )
      )
    )
 )
 (*error* nil)
)
Not totally the result you hoped for, but at least you wont have to go into settings to remove the center line.

Week-end-ô-clock!

 

Thanks all,

-Nobull

Posted

I think you just duplicated some code and took some things you should not have taken, because in the code you posted in your previous reply has partial duplicates and my "week-end-o-clock note in the middle. You must be careful with lisp, removing or adding a single parenthesis will inevitably make something fail. There's the code with both updates, but please pay close attention to the note I will post after.

 

 

(vl-load-com)
(defun c:OO () (c:OffsetPlus))
(defun c:OffsetPlus (/ *error* _OffsetPlus:Settings _OffsetPlus:Distance
                    sel dist v acDoc
                   )
 (defun *error* (msg)
   (if acDoc
     (vla-endundomark acDoc)
   )
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
   )
   (princ)
 )
 (defun _OffsetPlus:Settings (/ erase)    
   (initget "No Yes")
   (or (setq erase
              (getkword
                (strcat "\nErase selection [No/Yes]"
                        (if *OffsetPlus_KEEP*
                          " <Yes>: "
                          ": "
                        )
                )
              )
       )
       (setq erase *OffsetPlus_KEEP*)
   )
   (setq *OffsetPlus_KEEP*
          (if (= "No" erase)
            T
            nil
          )
   )
   (c:OffsetPlus)
 )
 (defun _OffsetPlus:Distance (sel / dist)
   (not (initget (+ 32 128)))
   (or (setq dist
               (getdist
                (cadr sel)
                (strcat "\nSpecify offset distance"
                        (if *OffsetPlus_Distance*
                          (strcat " <" (rtos *OffsetPlus_Distance*) ">: ")
                          ": "
                        )
                )
              )
       )
       (setq dist *OffsetPlus_Distance*)
   )
   (setq *OffsetPlus_Distance* dist)
 )
 (if
   (and
     (or
       (setq sel
              (entsel "\nSelect object to offset, <Enter> for Settings: "
              )
       )
       (_OffsetPlus:Settings)
     )
     (_OffsetPlus:Distance sel) 
     (setq v (vlax-ename->vla-object (car sel)))
   )
    (progn
      (vla-startundomark
        (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
      )
      (foreach d (list (abs (* 0.5 *OffsetPlus_Distance*))
                       (* -0.5 *OffsetPlus_Distance*)
                 )
        (vla-offset v d)
      )
      (if (not *OffsetPlus_KEEP*)
        (vla-delete v)
        (progn
          (if (not (tblsearch "ltype" "center"))
            (vla-load (vla-get-linetypes acDoc) "center" "ACAD.LIN")
          )
          (vla-put-linetype v "center")
        )
      )
    )
 )
 (*error* nil)
)

 

 

I just noticed something, there is a HUGE flaw in your code: if you pick a point instead of giving a numerical input, the result will NEVER be good. Here's why. When you use entsel, it returns something like that

( (0.075661 -0.00120012 0.0))

that is the Entity name, and the coordinates of the pickbox you used to select the entity. for that exemple I picked a line drawn from (0,0) to (1,0). As you can see the Y coordinate is not on 0.. and it get worse as you zoom out..

( (0.514154 -0.544031 0.0))

And guess what?

...
(setq sel
              (entsel "\nSelect object to offset, <Enter> for Settings: "
              )
       )
....
..
...
(getdist
                (cadr sel)

Your code uses the coordinates of the pickbox returned by the entsel to calculate the distance.

If you want to pick a point to set the distance, you MUST use the nearest osnap for the pickbox to be on the line

( (0.13959 0.0 0.0))

..but again, like I said on my 1rst post, dividing the distance of the offset by 2 (like it is now) also affects a picked offset by 2, meaning if you have a center line, choose it, and pick a point where a flange would stand, lets say 1 inch away, it wont work anymore as now the "oo" command will offset by 0.5 inch each side.

Posted

Thanks for the updated code Jef! and your time to do so. I'm definitely a beginner with code. At this point, copy, paste and pray is the extents of my skills with lisp. I'm just starting to be able to manipulate code a little but my troubleshooting skills are almost non-existent. I adjusted per your update and it works great. I'll try to heed your advice above.

 

As far as the pick point option of the code, I don't think I will ever use that. I always have the beam size in front of me. I believe this code originated from the Lee-mac link that is posted above if anyone reading this needs the original function. Big thanks to all who helped tweak this and thanks as always to Lee Mac. He always seems to be a part of a post around here even if he comments or not.

 

-Nobull

Posted

You should always credit the original code author.

Posted
You should always credit the original code author.

 

I always intend on giving the credit. In this case, I forgot where it came from until it was reposted. There was no author info in the code I had but I will definitely try to find that before posting. Thanks

Posted

I was challenged by someone at work to automate this further.... We have a beam in CAD that is "basically" a polyline. The information stored under properties has the beam size. Would there be a way to run a command, pick the object(s) and automatically double offset, with a line, on either side half the size of the beam, resulting in showing the edge of flanges? Basically, something that could read what size is stored in the properties and automate the lines. If someone is bored??

 

Thanks,

-Nobull

Posted

The properties do not store the size of the beam this may be xdata attached to the pline which is shown also in the properties or is it just a layer name 250UB25

 

Please post a screen shot of the properties.

Posted

I can't seem to post the screenshot. I used the icon above and tried to upload the png file but nothing happens. Not a big image.... The beam line is created by a custom lisp program my company had made. I've been able to add the name of the object or the specific layer it produces into other lisps so that they interact with the beam line. The other issue is I am weary of sharing too much about this as it is not my property to share. I'm absolutely sure there are restrictions against sharing too much about these. I think this may be something I might have to tackle on my own if/when I a have a better understanding of lisp and things like xdata. If you have ideas that would be great but I can't really expect anyone here to do much without all the object's info. Thanks for the response.

 

-Nobull

Posted

Go advanced, manage attachments, browse, upload, insert inline, works for me.

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