Jump to content

Recommended Posts

Posted

Hi, sorry for the confusing title, not sure how to label this.

 

If been searching for a fast way of finding out if a command was succesfull in creating what it was asked for, specifically with the OFFSET command, and select the generated objest(s). Basically, I have a LISP routine that offsets a polyline to the inside, but I want it to offset the object indefinitely until it can't be offset any more. See attachment.

 

So, if I use OFFSET to the inside of a polyline, 3 things can happen:

 

1) Polyline is offset and creates one polyline inside the other

2) Polyline is offset but creates more than one polyline inside the other, this happens if shape is irregular, and I need to select all created offset plines to continue offsetting them

3) The offset value is to big and no objects are generated

 

If I do this manualyy I get to a point where OFFSET command returns "Cannot offset that object" in the command line, is there any way of catching that message inside LISP? Or is the command returning an error?

Or when EXTEND returns "Object does not intersect an edge"

 

So far my options are:

 

Option 1) Set a variable with getlast, execute the command and check if getlast value changed. I tried this and it works, however, this only tells me if an object was created, but not how many or their IDs.

 

Option 2) Execute the command in a new layer and then select all objects on the layer (I don't have much experience on how to do this but I'm pretty sure it's possible) which I guess would return NIL if no object was created.

 

I've done some research on the ssget options but none of them seem to work for me, I even found a LISP to set a pline as selection boundary, but I have no warranty that there won't be other objects inside the newly created plines.

 

Anyone with ideas for a faster/easier way of doing this? I'm quite new with the whole LISP programming so still not sure how some things work.

 

Sorry if the post is long, I tried to include most of what I have found/tried till now. Have a nice day

offset.dwg

Posted

PD, I also researched on "vl-cmdf", but as I understand this will always return "T" even if the command is not executed. Thanks.

Posted

Two methods that come to mind....

 

If you're going to repeatedly call Command, store ENTLAST, call your Command, and compare another call to ENTLAST against the previously stored value. If not equal, overwrite your original value with the new, and repeat the sequence again.

 

Depending on your proficiencies, you could otherwise use Visual LISP to invoke the Offset() Method, and hook the ObjectAppended Event to determine same. This option is admittedly more complex, yet more efficient, particularly for large areas.

 

Cheers

Posted

I've been using a couple of visual lisps but I just copied them from internet sites, so not much experience on that. I did a little research on the offset () method but although it seems to return the data for the drawed objects, I'm still not sure how it would return it if more than two were created. Something is mentioned about a variant that returns the data in the form of a "variant array", not really sure about what that means. I'll play around with it a little bit as soon as I have some time and see how it works.

Posted

Compare the return values of both:

 

(vla-offset <obj> <distance>)

 

 

... And:

 

(vlax-invoke <obj> 'offset <distance>)

Posted (edited)

Perfect, using (vlax-invoke 'offset ) will draw the objects and also return a list with the names of all objects created by the command, something like this:

 

(#<VLA-OBJECT  IAcadLWPolyline 01ece35c> #<VLA-OBJECT IAcadLWPolyline  01ed026c> #<VLA-OBJECT IAcadLWPolyline 01ed02bc>)

 

Based on this LISP from CAB in http://www.theswamp.org/index.php?topic=2899.5;wap2 , I used the following:

 

(defun c:offset (/ ename dist err_obj vobj enew)
(setq enew (entlast))
(vl-load-com)
   (and
       (null (initget 7))
       (setq dist (getdist "\nEnter offset distance: "))
       (while (setq ent (entsel "\nSelect object to offset."))
           (if (and (setq vobj (vlax-ename->vla-object (car ent)))
                   (vlax-method-applicable-p vobj "Offset")
               )
               (progn
                   
                   (if (vl-catch-all-error-p
                       (vl-catch-all-apply 'vlax-invoke
                       (list vobj 'Offset (- dist))))
                       (prompt "\nNegative distance failed.")
                        (setq enew (vlax-invoke vobj 'offset (- dist)));  This makes the offset done twice, must put it inside the error catch,  but how??
                   )
               )
               (prompt "\n*** Can not offset that object, try again. ***")
           )
       )
   )
   (princ)
)
(princ)

 

so all have to do is modify so it takes the list from the "vlax-invoke" instead of asking again to select the next object, which should be easy. However, it gets the offset drawn twice (obviously since it has two calls to offset within the "if"), so I was looking into placing the

 

(setq enew (vlax-invoke vobj 'offset (- dist)))

 

line inside the error catching but wasn't avail to make it work. I'll leave that for later since it's too late already.

 

Thanks for all the help and comments!!

Edited by cletero
placing code tags
Posted

You're welcome; I'm happy to help... Thank you, for crediting your source. :beer:

 

 

 

... Just remember to use

 tags. :thumbsup:

 

Cheers

Posted

Thanks also for the tip on code tags, didn't know about it (as usual, I didn't read the "how to post" guide) but certainly does make life easier when reading :thumbsup:, so I edited my previous post

Posted

No worries; we all start somewhere. :)

 

You have a handle on what you're doing before asking for help, you credit your sources, and you proactively revised your posts to add

 tags... You're going to fit in just fine here. :thumbsup:
Posted (edited)

Finally, here it is, it will offset multiple objects, multiple times. See instructions within code to understand how it works. Any comments/improvements are welcome. Of course, I have to say I'm not a lisp professional, so I can't guaranty any results obtained with this code, so use with care.

 

I have two questions though:

1) If i use the "undo" command after using this lisp, it will undo the offset(s) plus the last action before the lisp (ej, if I draw a circle and then use this lisp to offset it, and then hit "Undo", it will erase the offset plus the circle) Any thoughts?

2) Is there any way to avoid the user entered variables appearing in the command history?

 

;Alfredo Rodriguez, 18 May 2014
;This will offset an object multiple times
;It will offset to the inside/outside, up/down, left/right depending on the drawing direction
;So it's better to always set a maximum number of offsets or else it could offset indefinitely
;For this reason, if use default is chosen, it will offset the object 20 times, or you can
;choose how many times to offset. If object is offset to the wrong side, enter a negative distance (ej: -3 instead of 3)
;I'm not a lisp professional, so I can't guaranty any results obtained with this code, so use with care.
(defun c:cntoffset (/ ename dist vobj obj objlist objlist2 how_many count maxcount)
(vl-load-com)

       (null (initget 7))

       (while (setq ent (ssget))
           (setq dist (getdist "\nEnter offset distance: "))
           (setq how_many (sslength ent))
           (setq count 0)
       
            (or
           (setq maxcount (getdist "\nEnter number of offsets (or press Enter to use default): "))
           (setq maxcount 20)
           )
           
           (while (/= count how_many)
               (setq ename (ssname ent count))
               (setq obj (list (vlax-ename->vla-object ename)))
                 (setq objlist (append obj objlist))
               (setq count (+ count 1))
           )
           (setq count 0)
           (while (and (/= count maxcount) (/= objlist nil))
               (setq count (+ count 1))
               (foreach vobj objlist
                   (if (vlax-method-applicable-p vobj "Offset")
                       (if (vl-catch-all-error-p
                           (setq objlist2 (vl-catch-all-apply 'vlax-invoke
                           (list vobj 'Offset (- dist)))))
                           (setq objlist2 nil)
                       )
                   (prompt "\n*** Can not offset that object, try again. ***")
                   )
                   (setq objlist (append (cdr objlist) objlist2))
               )
       
           )
             (setq objlist nil)
             (setq objlist2 nil)
       )

   (princ)
)

Thanks again for all the help. Have a nice day!!8)

Edited by cletero

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