3dwannab Posted January 24 Posted January 24 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. Quote
pkenewell Posted January 24 Posted January 24 (edited) @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 January 24 by pkenewell 1 Quote
3dwannab Posted January 24 Author Posted January 24 @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. Quote
pkenewell Posted January 29 Posted January 29 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. Quote
BIGAL Posted January 30 Posted January 30 (edited) 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 January 30 by BIGAL 1 Quote
pkenewell Posted February 22 Posted February 22 @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. 1 Quote
SLW210 Posted February 23 Posted February 23 Originally, the APP was a LISP according to the description, now it is done in .NET. Maybe you can locate the original LISP. Lee Mac has a Dynamic Offset, have you tried that? This One at Cadalyst sounds close to the one in the APP store, but seems to be gone now. Quote
pkenewell Posted February 23 Posted February 23 1 hour ago, SLW210 said: Lee Mac has a Dynamic Offset, have you tried that? Lee Macs Dynamic Offset offsets to both sides, so there is no method of determining which side to offset. Quote
SLW210 Posted February 23 Posted February 23 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 Quote
pkenewell Posted February 23 Posted February 23 (edited) 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 February 23 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. 1 Quote
3dwannab Posted February 23 Author Posted February 23 Brilliant stuff @pkenewell, this is brilliant for footpaths, cavity walls and other things I can't think off atm. 2 Quote
pkenewell Posted February 23 Posted February 23 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. 1 1 Quote
pkenewell Posted February 23 Posted February 23 (edited) @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 February 23 by pkenewell 1 1 Quote
BIGAL Posted February 24 Posted February 24 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 ...... ) 1 Quote
3dwannab Posted October 23 Author Posted October 23 (edited) On 2/23/2024 at 8:36 PM, pkenewell said: @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". I've just tried to change this to offset from the original line. If I enter 100 200 as the offset, i was looking for the first offset to be 100 and then the other 300 (100+200). So, if I enter 100 150 100 it will draw me a cavity wall with 100 inner leaf/150 cavity/100 outer leaf. I thought by adding (setq n (+ n n) in the foreach loop it would do that. (foreach n (mapcar 'distof tl) ;; Not worky (setq n (+ n n)) (setq t1 (car (vlax-invoke ob "offset" (+ n 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) ) ) Fixed it. Added revision edit in the header. Thanks again @pkenewell for this. It's a huge timesaver. ;|============================================================== moff.lsp by Phil Kenewell - 2/23/2024 Description: This routine contains the 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: - 2024.02.23: Changed using "atof" to "distof" to allow fractions, etc. - 2024.10.23: (Edit by 3dwannab) - Change the offset to offset incrementally. - Entering 100 150 100 will draw a cavity wall with a 100 inner leaf/150 cavity/100 outer leaf. - Command is now moffi to reflect the change to an incremental multiple offset. - Added undo handling. ===============================================================|; (defun c:moffi (/ *error* _strparse ds ob op s t1 t2 tl inc) (defun *error* (errmsg) (and acDoc (vla-EndUndoMark acDoc)) (and errmsg (not (wcmatch (strcase errmsg) "*CANCEL*,*EXIT*")) (princ (strcat "\n<< Error: " errmsg " >>\n")) ) (setvar 'cmdecho var_cmdecho) (setvar 'osmode var_osmode) ) ;; Start the undo mark here (setq acDoc (vla-get-ActiveDocument (vlax-get-acad-object))) (or (vla-EndUndoMark acDoc) (vla-StartUndoMark acDoc)) ;; 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)))) (setq inc 0.0) ; Initial value of i as a float ;; iterate for each dist (foreach n (mapcar 'distof tl) (setq inc (+ inc n)) ; Increment n by each element in the list so the offset happens incrementally (setq t1 (car (vlax-invoke ob "offset" inc)) t2 (car (vlax-invoke ob "offset" (- inc))) ) (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.") ) ) (vla-EndUndoMark acDoc) (*error* nil) (princ) ) ;;(c:moffi) ;;; Unblock for testing Edited October 23 by 3dwannab 1 Quote
3dwannab Posted October 23 Author Posted October 23 The reason for the edit was I am working on a cavity wall 102.5 outer brick leaf / 150 cavity / 215 inner leaf / 18mm plaster so that would translate to 102.5 252.5 467.5 485.5. That would give an aspirin a headache trying to remember that, well me anyway!! 1 Quote
BIGAL Posted October 23 Posted October 23 (edited) Why not use a Mline then can draw walls as in plural. This is a make mline. ; make mline ; By alan H oct 2020 ; Set to bylayer at moment ; Thanks to FIXO for original code (defun c:makml ( / lst1 lst2 lst desc MLINE_STYLE_NAME ) (setq MLINE_STYLE_NAME (getstring "\nEnter mline name ") desc (getstring "\nEnter description ") ) (while (setq off (getreal "\Enter offset Enter to finish " )) (setq lst (cons off lst)) ) (if (= desc nil)(setq desc MLINE_STYLE_NAME)) (setq lst1 (list '(0 . "MLINESTYLE") '(100 . "AcDbMlineStyle") (cons 2 MLINE_STYLE_NAME) (cons 70 (+ 272)) (cons 3 desc) '(62 . 256) (cons 51 (/ pi 2.)) (cons 52 (/ pi 2.)) '(71 . 4) '(72 . 4) ) ) (setq x (length lst)) (repeat x (setq lst2 (list (cons 49 (nth (setq x (- x 1)) lst)) (cons 62 256) (cons 6 "BYLAYER") ) ) (setq lst1 (append lst1 lst2)) ) (if (not (dictadd (cdar (dictsearch (namedobjdict) "ACAD_MLINESTYLE")) MLINE_STYLE_NAME (entmakex lst1) ) ) (Alert "Impossible to create mline style\n perhaps this was exist earlier") ) (setvar 'cmlstyle MLINE_STYLE_NAME) (princ) ) (c:makml) Edited October 23 by BIGAL Quote
pkenewell Posted October 24 Posted October 24 15 hours ago, 3dwannab said: The reason for the edit was I am working on a cavity wall 102.5 outer brick leaf / 150 cavity / 215 inner leaf / 18mm plaster so that would translate to 102.5 252.5 467.5 485.5. That would give an aspirin a headache trying to remember that, well me anyway!! @3dwannab That's cool - I completely understand. Glad you could alter the code to fit your needs! 1 Quote
Recommended Posts
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.