AutoLISP for offsetting

AutoLISP for offsetting

Anonymous
Not applicable
12,720 Views
16 Replies
Message 1 of 17

AutoLISP for offsetting

Anonymous
Not applicable

Hi all,

 

 

I am a beginner to AutoLISP and I am trying to write a lisp that will allow me to select 1 line/polyline and offset that line/polyline to multiple pre-set distances all to the same side. I would like to write a lisp that will allow me to do this in just 2 clicks, the first click on the line/polyline that I would like to offset and the second click for what side of the line/polyline I would like to offset to.

 

I have tried writing lisps using setq and getpoint but I can't get the offset command to register the variable name with lisp. Does anyone have any ideas?

 

 

PolylinePolylinePolyline offset to 50, 150 and 250Polyline offset to 50, 150 and 250 

 

 

 

0 Likes
Accepted solutions (4)
12,721 Views
16 Replies
Replies (16)
Message 2 of 17

Ranjit_Singh
Advisor
Advisor
Accepted solution

Maybe something like this

(defun c:somefunc  (/ ent pt)
 (setq ent (car (entsel "\nSelect polyline to offset: "))
       pt  (getpoint "\nSelect side to offset: "))
 (foreach i '(50 150 250) (command "._offset" i ent pt "")))

offset_multiple.gif

 

Message 3 of 17

Shneuph
Collaborator
Collaborator
Accepted solution
(Defun C:MultiOffset ( / p1 ob1)
  (command "offset" 50 (setq ob1 (entsel))  (setq p1 (getpoint)) "")
  (command "offset" 150 ob1 p1 "")
  (command "offset" 250 ob1 p1 "")
  (princ)
  );defun

Very basic but I believe it works how you like it.  Maybe one of the gurus could post a better (although more complex) solution with error checking etc.  Not using the command function as well.

---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
Message 4 of 17

john.uhden
Mentor
Mentor

I think that your offering is very concise and works perfectly.  Nice work!

John F. Uhden

0 Likes
Message 5 of 17

Anonymous
Not applicable

Thank you for the above suggestions! They are much appreciated!

 

I failed to mention that I would also like for each line that has been created by offsetting to be on a separate pre-set layers, as in my below picture where each new line is on a separate layer; red, green or blue. I have had a look at both of the above lisps and I cannot work out how amend the code to make that happen.

 

Polyline offset with new lines on layers; red, green and bluePolyline offset with new lines on layers; red, green and blue

 

 

 

0 Likes
Message 6 of 17

Ranjit_Singh
Advisor
Advisor
Accepted solution
(defun c:somefunc  (/ ent pt etdata)
 (setq ent (car (entsel "\nSelect polyline to offset: "))
       pt  (getpoint "\nSelect side to offset: "))
 (foreach i '((50 . “Layer1”) (150 . “Layer2”) (250 . “Layer3”))
(command "._offset" (car i) ent pt "")
(entmod (subst (cons 8 (cdr i)) (assoc 8 (setq etdata (entget (entlast)))) etdata))))

 

Message 7 of 17

Kent1Cooper
Consultant
Consultant
Accepted solution

Picking up on @Shneuph's approach, but consolidating into just one  (command) function:

 

(Defun C:MultiOffset (/ p1 ob1)
  (command
    "_.offset" 50 (setq ob1 (entsel)) (setq p1 (getpoint)) ""
    "_.chprop" "_last" "" "_layer" "LayerA" ""
    "_.offset" 150 ob1 p1 ""
    "_.chprop" "_last" "" "_layer" "LayerB" ""
    "_.offset" 250 ob1 p1 ""
    "_.chprop" "_last" "" "_layer" "LayerC" ""
  ); command
  (princ)
);defun
Kent Cooper, AIA
Message 8 of 17

john.uhden
Mentor
Mentor

That didn't work too well in my ACAD 2002...

 

Command: somefunc

Select polyline to offset:
Select side to offset: ._offset
Specify offset distance or [Through] <4'-2">: 50
Select object to offset or <exit>:
Specify point on side to offset:
Select object to offset or <exit>:
Command: ; error: bad DXF group: (8 . “LAYER1”)

Doesn't the layer have to exist first?

John F. Uhden

0 Likes
Message 9 of 17

john.uhden
Mentor
Mentor

Didn't work very well for me in ACAD2002...

 

Command: multioffset
_.offset
Specify offset distance or [Through] <4'-2">: 50
Select object to offset or <exit>:
Select object:
Specify point on side to offset:
Select object to offset or <exit>:
Command: _.chprop
Select objects: _last 1 found

Select objects:
Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness]: _layer
Enter new layer name <0>: LayerA
Cannot find layer "LayerA".
; error: Function cancelled

I think the layer has to exist first.

John F. Uhden

0 Likes
Message 10 of 17

devitg
Advisor
Advisor

It is better create as many layers , as offset to do , Or chek if exist, else make layer.

 

0 Likes
Message 11 of 17

fcolocho
Contributor
Contributor

Good afternoon,

I checked on this code and I like the idea of specific offset distances and specific layers, however, is possible to make the routine to offset those lines on both sides of the centerline?

Thank you.

0 Likes
Message 12 of 17

Kent1Cooper
Consultant
Consultant

@fcolocho wrote:

... is possible to make the routine to offset those lines on both sides of the centerline? ....


If you mean on both sides to the same set of distances and to the same Layers, that's easier in a way, because it does not require the User to specify a side.  The (vla-offset) function can just do it twice, once with a positive distance and once with a negative.

(defun C:MultiOffsetB (/ esel obj); = Multiple Offsets to Both sides
  (if
    (and
      (setq esel (entsel "\nObject to Offset to both sides at mulitple distances & to multiple Layers: "))
      (wcmatch (cdr (assoc 0 (entget (car esel)))) "LINE,*POLYLINE,ARC,CIRCLE,ELLIPSE,SPLINE,XLINE")
    ); and
    (progn ; then
      (command "_.layer" "_new" "LayerA,LayerB,LayerC" ""); ensure they exist
      (setq obj (vlax-ename->vla-object (car esel)))
      (foreach pair '((50 "LayerA") (150 "LayerB") (250 "LayerC"))
        (vla-offset obj (car pair))
        (command "_.chprop" "_last" "" "_layer" (cadr pair) "")
        (vla-offset obj (- (car pair)))
        (command "_.chprop" "_last" "" "_layer" (cadr pair) "")
      ); foreach
    ); progn
  ); if
  (prin1)
)

I added the LAYER command to ensure the Layers exist -- it won't matter if they already do.  Any that do not will get default properties like color 7 and continuous linetype; any that do will keep their properties.  If they might not exist, that could be expanded to give them colors/linetypes/etc. as you prefer.

And I added an entity-type check.  One curiosity is that for some reason the (vla-offset) approach does not work on RAYs, even though ordinary OFFSET does.  So to include them would require an OFFSET-command-based approach, or some calculations for COPY, or something.  It could be made a little more sophisticated to check that a Polyline is not 3D [those can't be Offset].

 

BY THE WAY, I notice some "smart quotes" in some of the earlier routines -- someone must have written them in a word-processor rather than in a plain-text editor.  That could explain some of the problems noted.

Kent Cooper, AIA
Message 13 of 17

fcolocho
Contributor
Contributor

Perfect!

That is what I needed it. Thank you very much.

0 Likes
Message 14 of 17

Sea-Haven
Mentor
Mentor

Another method is ask for offsets so type 50,-50,30,40,-40 this will do right and left offsets based on the method of -ve values go left. 

 

If you have fixed offsets why not use MLINE you can make a lisp that creates the MLINE if it does not exist, advantage is you can have multi layer as well. Just ask.

0 Likes
Message 15 of 17

Kent1Cooper
Consultant
Consultant

@Sea-Haven wrote:

.... the method of -ve values go left. ....


For most things, but not for LINEs or XLINEs -- positive values go left for them.

Kent Cooper, AIA
0 Likes
Message 16 of 17

Sea-Haven
Mentor
Mentor

I was thinking of closed plines in a CCW direction using VL-offset +ve goes out -ve goes in, yes lines go left. Circles and arcs increase for +ve values

0 Likes
Message 17 of 17

fcolocho
Contributor
Contributor

Good additional ideas, but I think the lisp from Kent work better for what I need. Thank you for the input.

0 Likes