Jump to content

Offset with list (like Multiple Offset on the appstore)


3dwannab

Recommended Posts

Hi all,

 

I was looking if there was an existing routine to do the same as this on the appstore whereby you can input to the commandline this for instance '200 500 555' and it will offset to those 3 distances?

 

 

https://apps.autodesk.com/ACD/en/Detail/Index?id=7131157146074921574&appLang=en&os=Win32_64#:~:text=MOffset fills this gap by,is the integration with AutoCAD.

Link to comment
Share on other sites

@3dwannab Here is the simplest way - no minimal error checking:

(defun c:moff (/ *error* _Strparse cnt dstr en go op s tl)
   
   (defun *error* (msg)(if oc (setvar "cmdecho" oc))(princ msg))
   
   (setq oc (getvar "cmdecho"))
   (setvar "cmdecho" 0)
   (command "._undo" "_BE")
   
   (defun _StrParse (str del / pos)
     (if (and str del)
        (if (setq pos (vl-string-search del str))
          (cons (substr str 1 pos) (_StrParse (substr str (+ pos 1 (strlen del))) del))
          (list str)
        )
     )
   ) 

   (if (and
         (setq dstr (getstring t "\nEnter Distances separated by spaces: "))
         (setq s (entsel "\nSelect a curve to offset: "))
         (setq en (car s) cnt 0)
         (setq go (wcmatch (cdr (assoc 0 (entget en))) "LINE,*POLYLINE,SPLINE,XLINE,CIRCLE,ARC,ELLIPSE"))
         (setq op (getpoint (cadr s) "\nSelect side to Offset: "))
      )
      (if (setq tl (_Strparse dstr " "))
         (foreach n tl
           (command "._offset" (nth cnt tl) en "_non" op "")
           (setq cnt (1+ cnt))
         )
      )
      (if (not go)(princ "\nInvalid Object Selected."))
   )

   (command "._undo" "_E")
   (setvar "cmdecho" oc)
   (princ)
)

 

Edited by pkenewell
  • Thanks 1
Link to comment
Share on other sites

@pkenewell, nice code. I was sure there was something like this out in the wild somewhere but I couldn't find it. I like the portability of LISPs' without having to install for future versions like appstore apps.

 

Thanks very much.

Link to comment
Share on other sites

On 1/24/2024 at 10:30 AM, 3dwannab said:

I was sure there was something like this out in the wild somewhere but I couldn't find it.

@3dwannab Glad you like it! LOL - there probably is something out there, but I just wrote it for you on the fly since it was a fairly simple task.

Link to comment
Share on other sites

I have another trying to find it, if you use VLA-Offset you can supply +ve and -ve values so will go left and right without need for direction pick, with open plines and lines select near an end implies the direction of the linework so goes right with +ve values. 

 

Arcs and circles reduce or increase radius.

Edited by BIGAL
  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

@3dwannab I'm have been working on a solution that doesn't use command, but it is not as easy as it seems. Determining the side to offset is a different challenge depending on the object selected and whether it is closed or open. I haven't determined a version that works for everything yet. It's MUCH less code just to use the offset command.

  • Like 1
Link to comment
Share on other sites

1 hour ago, pkenewell said:

Lee Macs Dynamic Offset offsets to both sides, so there is no method of determining which side to offset.

 

Read the instructions again, you hit Tab to switch between either side or both. 

 

Quote

Offset Mode     Can be changed by pressing Tab, the user has the ability to offset the set of objects to either side, or both sides simultaneously

 

Link to comment
Share on other sites

6 hours ago, SLW210 said:

 

Read the instructions again, you hit Tab to switch between either side or both. 

 

 

 

@SLW210 Sorry you're right. It conveniently gives you a preview to determine which side. That's something I hadn't thought of!

 

@3dwannab FWIW. I did figure out something with some ingenious ideas from both LeeMac and RonjonP, that make the code pretty short. It may not work perfectly in every instance unless you set your "select offset side" point well out past all the distances you enter (EDIT - I think I solved this). See the code below:

;|==============================================================
moff.lsp by Phil Kenewell - 2/23/2024

Description:
  This routine contain command MOFF, or Multiple Offset. It allows
  you to enter multiple offset distances, separated by spaces and
  will offset all those distances to the side you specify.
  
Some code Inspired by:
   RonJonP: https://www.theswamp.org/index.php?topic=24688.msg297553#msg297553
   Lee Mac: https://www.theswamp.org/index.php?topic=32743.0

Last Update:
   - 2/23/2024: changed using "atof" to "distof" to allow fractions, etc.

===============================================================|;
(defun c:moff (/ _strparse ds ob op s t1 t2 tl)

   ;; Sub function to Parse a string by the specified delimiter.
   (defun _StrParse (str del / pos)
     (if (and str del)
        (if (setq pos (vl-string-search del str))
          (cons (substr str 1 pos) (_StrParse (substr str (+ pos 1 (strlen del))) del))
          (list str)
        )
     )
   )

   
   (if
      (and
         (setq ds (getstring t (strcat "\nEnter Distances separated by spaces: <" (if pjk:offdist pjk:offdist "") ">"))
               ds (if (= ds "") pjk:offdist (setq pjk:offdist ds))
         )
         (/= ds "")
         (setq tl (_Strparse ds " "))
         (> (apply '+ (mapcar 'distof tl)) 0.0)
      )
      (if (and
            (setq s  (entsel "\nSelect a curve to offset: "))
            (setq ob (vlax-ename->vla-object (car s)))
         )
         (if (not (vlax-method-applicable-p ob 'Offset))
           (princ "\nInvalid object for Offset. ")
           (if (setq op (getpoint (cadr s) "\nSelect side to Offset: "))
               (progn
                  ;; Make sure the offset side point at the outside of the offset zone.
                  (setq op (polar (cadr s) (angle (cadr s) op) (apply '+ (mapcar 'atof tl))))
                  ;; iterate for each dist
                  (foreach n (mapcar 'distof tl)
                     (setq t1 (car (vlax-invoke ob "offset" n))
      	                  t2 (car (vlax-invoke ob "offset" (- n)))
                     )
                     (if
                        (< (distance op (vlax-curve-getclosestpointto t1 op))
      	                  (distance op (vlax-curve-getclosestpointto t2 op))
      	               )
                        (vla-delete t2)
                        (vla-delete t1)
                     )
                  )
               )
            )
         )
      )
      (progn
         (setq pjk:offdist nil)
         (princ "\nInvalid Distances Entered.")
      )
   )
   (princ)
)

 

Edited by pkenewell
Change program flow to add better handling of errors, such as an invalid string entered for distances. EDIT 2: changed "atof" to "distof" to allow fractions, etc.
  • Like 1
Link to comment
Share on other sites

20 minutes ago, 3dwannab said:

Brilliant stuff @pkenewell, this is brilliant for footpaths, cavity walls and other things I can't think off atm.

 

👏

@3dwannab Thanks!

NOTE: I updated the code in my previous post to have better error handling if someone enters an invalid string for the distances. Please re-copy it.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

@3dwannab FYI - I changed the code above again to allow different units, like fractions, architectural, etc. Simple change from using "atof" to convert the strings to using "distof".

Edited by pkenewell
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Just a comment or 2,

 

a closed object when offset to outside the area will be bigger than original so a +v or -ve can be implied, just check and erase if required uses VLA-offset. Hint recent post forums/autodesk.

 

an open object like a line or pline you pick near an end this implies the direction of the line a simple little defun can check. You get used to it, yes vertical lines etc.

 

Just for illustration needs line or pline handled differently.

(setq ent1 (entsel "\nPick line 1 TP end "))
(setq pt1 (cadr ent1))
(setq ent1g (entget (car ent1)))
(setq pt10 (cdr (assoc 10 ent1g)))
(setq pt11 (cdr (assoc 11 ent1g)))
(setq d1 (distance pt1 pt10))
(setq d2 (distance pt1 pt11))
(if (> d1 d2)
; swap offset +ve -ve value
......
)

 

  • Like 1
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...