Community
AutoCAD Forum
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Offset/trim to turn intersecting lines into 2d shapes for complex laser cut

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
Anonymous
2020 Views, 9 Replies

Offset/trim to turn intersecting lines into 2d shapes for complex laser cut

Anonymous
Not applicable

Hi folks,

 

First time posting on these forums, long time lurker though. Very helpful community, thanks to all the people who spend time answering questions here.

 

Anyway, here's my question. Probably easiest to start with an image:

 

Capture.PNG

Suppose I start with the large dashed lines basically as guidelines for a complex design intended to be laser cut (I'm aware of the need to smooth corners etc - I'm not looking for laser cutting advice here, this is purely a CAD problem), but I need these lines to have dimension. So I offset them as per the arrows, and then trim the overlapping bits as per the small dashed lines. This gives me what I want, but requires a total of 10+ actions per intersection with all the offseting and trimming that needs to happen. For a little more context, here's a small section of a design I've already done this with:

 

Capture2.PNG

 

All of this was created through the offset/trim method above. Wasn't too much of a problem due to the grid regularity, so only needed to do it to a small portion then polar array the result. But now I'm working on something like this:

 

Capture3.PNG

 

Where all the lines above correspond to the dotted guidelines in the original image. There's no regularity in the 'grid' here that I can exploit with arraying/mirroring and it seems infeasible to do the 10+ actions on every single intersection.

 

It would be great if I could do something like give all the lines a width (visually turning them into solid overlapping rectangles...ish) then generate an outline of the resulting geometry, but obviously acad's width property doesn't actually make things 2d. The .TRACE command seems to be the closest thing I've found here, but I think that'd still require a ton of trimming, even if it saves me time on offsetting.

 

Hope this explanation is sufficiently clear. Any ideas? LISP routines? Thanks for any help here, people.

0 Likes

Offset/trim to turn intersecting lines into 2d shapes for complex laser cut

Hi folks,

 

First time posting on these forums, long time lurker though. Very helpful community, thanks to all the people who spend time answering questions here.

 

Anyway, here's my question. Probably easiest to start with an image:

 

Capture.PNG

Suppose I start with the large dashed lines basically as guidelines for a complex design intended to be laser cut (I'm aware of the need to smooth corners etc - I'm not looking for laser cutting advice here, this is purely a CAD problem), but I need these lines to have dimension. So I offset them as per the arrows, and then trim the overlapping bits as per the small dashed lines. This gives me what I want, but requires a total of 10+ actions per intersection with all the offseting and trimming that needs to happen. For a little more context, here's a small section of a design I've already done this with:

 

Capture2.PNG

 

All of this was created through the offset/trim method above. Wasn't too much of a problem due to the grid regularity, so only needed to do it to a small portion then polar array the result. But now I'm working on something like this:

 

Capture3.PNG

 

Where all the lines above correspond to the dotted guidelines in the original image. There's no regularity in the 'grid' here that I can exploit with arraying/mirroring and it seems infeasible to do the 10+ actions on every single intersection.

 

It would be great if I could do something like give all the lines a width (visually turning them into solid overlapping rectangles...ish) then generate an outline of the resulting geometry, but obviously acad's width property doesn't actually make things 2d. The .TRACE command seems to be the closest thing I've found here, but I think that'd still require a ton of trimming, even if it saves me time on offsetting.

 

Hope this explanation is sufficiently clear. Any ideas? LISP routines? Thanks for any help here, people.

9 REPLIES 9
Message 2 of 10
Moshe-A
in reply to: Anonymous

Moshe-A
Mentor
Mentor
Accepted solution

@Anonymous  hi,

 

here is a quick autolisp command to do detailed offset. just copy & paste these code lines in notepad text file and save it as boffset.lsp than load the file into your drawing (or use appload) and key in BOFFSET command.

 

the command starts by pausing for Specify offset distance and by default it's set to 10.

next ask for Specify candidate set for boundary... which is needed to know what are the objects surrounding the boundary. next ask to Specify internal point ... the command than do an offset polyline. after the first offset it continue to ask for Specify candidate set for boundary...  and Specify internal point ... and do the next with the same offset distance. to exit just press enter and for changing the offset distance restart the command.

 

more about offset distance:

as you set a new default offset it will be your default offset next time but only for the current drawing session (next time you open the file it will be 10 again). be careful with this offset, specifying unreasonable value will run the command into error.

 

enjoy

moshe

 

(vl-load-com) ; load activex support

(defun c:boffset (/ askOffset ; local function
		    ofset ss p0 AcDbPolyline)
  
 (defun askOffset (msg def / ask)
  (initget 2)
  (if (not (setq ask (getdist (strcat "\n" msg " <" (rtos def 2) ">: "))))
   (setq ask def)
   (setq def ask)
  )
 ); askOffset

 ; here starts c:boffset
 (vla-startUndoMark (vla-get-activedocument (vlax-get-acad-object))) 
  
 (if (= (getvar "userr1") 0.0)
  (setq ofset 10.0)
  (setq ofset (getvar "userr1"))
 )

 (setvar "userr1" (setq ofset (askOffset "Specify offset distance" ofset)))
  
 (while (and
          (not (prompt "\nSpecify candidate set for boundary..."))
          (setq ss (ssget '((0 . "line,arc,circle,ellipse,spline,lwpolyline"))))
          (setq p0 (getpoint "\nSpecify internal point: "))
        )
   (command-s "._bpoly" "_Advanced" "_Boundary" "_New" "_si" ss "" p0 "")
   (setq AcDbPolyline (vlax-ename->vla-object (entlast))) ; allocating memory
   (vla-offset AcDbPolyline (* -1 ofset))
   (vla-delete AcDbPolyline)
   (vlax-release-object AcDbPolyline) ; dispose memory
 ); while

 (vla-endUndoMark (vla-get-activedocument (vlax-get-acad-object))) 
  
 (princ)  
); c:boffset

 

 

 

@Anonymous  hi,

 

here is a quick autolisp command to do detailed offset. just copy & paste these code lines in notepad text file and save it as boffset.lsp than load the file into your drawing (or use appload) and key in BOFFSET command.

 

the command starts by pausing for Specify offset distance and by default it's set to 10.

next ask for Specify candidate set for boundary... which is needed to know what are the objects surrounding the boundary. next ask to Specify internal point ... the command than do an offset polyline. after the first offset it continue to ask for Specify candidate set for boundary...  and Specify internal point ... and do the next with the same offset distance. to exit just press enter and for changing the offset distance restart the command.

 

more about offset distance:

as you set a new default offset it will be your default offset next time but only for the current drawing session (next time you open the file it will be 10 again). be careful with this offset, specifying unreasonable value will run the command into error.

 

enjoy

moshe

 

(vl-load-com) ; load activex support

(defun c:boffset (/ askOffset ; local function
		    ofset ss p0 AcDbPolyline)
  
 (defun askOffset (msg def / ask)
  (initget 2)
  (if (not (setq ask (getdist (strcat "\n" msg " <" (rtos def 2) ">: "))))
   (setq ask def)
   (setq def ask)
  )
 ); askOffset

 ; here starts c:boffset
 (vla-startUndoMark (vla-get-activedocument (vlax-get-acad-object))) 
  
 (if (= (getvar "userr1") 0.0)
  (setq ofset 10.0)
  (setq ofset (getvar "userr1"))
 )

 (setvar "userr1" (setq ofset (askOffset "Specify offset distance" ofset)))
  
 (while (and
          (not (prompt "\nSpecify candidate set for boundary..."))
          (setq ss (ssget '((0 . "line,arc,circle,ellipse,spline,lwpolyline"))))
          (setq p0 (getpoint "\nSpecify internal point: "))
        )
   (command-s "._bpoly" "_Advanced" "_Boundary" "_New" "_si" ss "" p0 "")
   (setq AcDbPolyline (vlax-ename->vla-object (entlast))) ; allocating memory
   (vla-offset AcDbPolyline (* -1 ofset))
   (vla-delete AcDbPolyline)
   (vlax-release-object AcDbPolyline) ; dispose memory
 ); while

 (vla-endUndoMark (vla-get-activedocument (vlax-get-acad-object))) 
  
 (princ)  
); c:boffset

 

 

 

Message 3 of 10
Anonymous
in reply to: Moshe-A

Anonymous
Not applicable

tyvm for this! Don't have the opportunity to give it a spin now, but will try it out later tonight and let you know how it goes

0 Likes

tyvm for this! Don't have the opportunity to give it a spin now, but will try it out later tonight and let you know how it goes

Message 4 of 10
Moshe-A
in reply to: Anonymous

Moshe-A
Mentor
Mentor

the lisp is base on BPOLY command so you should bring in consideration the state of these lines...if the lines does not form a close area BPOLY will fail.

 

 

0 Likes

the lisp is base on BPOLY command so you should bring in consideration the state of these lines...if the lines does not form a close area BPOLY will fail.

 

 

Message 5 of 10
Kent1Cooper
in reply to: Anonymous

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

....

It would be great if I could do something like give all the lines a width (visually turning them into solid overlapping rectangles...ish) then generate an outline of the resulting geometry....


 

Try OffsetBothSidesErase.lsp, with its OBSE command, available >here<, which will do that in one step, to as many at the same width as you want all at once.  That's assuming you don't  want the full perimeter including the ends, which I assume is the case from your description.

Kent Cooper, AIA
0 Likes


@Anonymous wrote:

....

It would be great if I could do something like give all the lines a width (visually turning them into solid overlapping rectangles...ish) then generate an outline of the resulting geometry....


 

Try OffsetBothSidesErase.lsp, with its OBSE command, available >here<, which will do that in one step, to as many at the same width as you want all at once.  That's assuming you don't  want the full perimeter including the ends, which I assume is the case from your description.

Kent Cooper, AIA
Message 6 of 10
Moshe-A
in reply to: Anonymous

Moshe-A
Mentor
Mentor

@Anonymous ,

 

i would love to hear how it works?

 

 

0 Likes

@Anonymous ,

 

i would love to hear how it works?

 

 

Message 7 of 10
Anonymous
in reply to: Moshe-A

Anonymous
Not applicable

Right, sorry, yeah, it works marvelously. Saved me legitimately hours of time on this project. Couple of minor notes:

1) It would be perfect if this worked with splines, but I personally work with them pretty rarely so for me this isn't that big of a deal

2) When trying to form a boundary with at least one side being a spline, the following sequence of events happens: 1) Select boundaries, 2) Specify internal point, 3) This is where weird stuff happens. First, a new line in the command window comes up saying "Polyline boundary could not be derived. Create Region? <Y> Polyline boundary could not be derived. Create Region? <Y>" - note the <Y> indicates the default option, not the choice specified by the user, and both of these appear at once on the same line ("line" here referring to the command line, not a line object in the drawing). Additionally, the previous line instead of saying "Specify internal point" as it did when originally prompting you, now says "Specify internal point or [Advanced options]". Example:

 

 

Capture4.PNG

 

The "Advanced options" thing isn't visible or accesible when you're actually being prompted to specify the internal point, and appears to be a side-effect of whatever intermediate magic this script is performing, since I don't see it anywhere in the code (though LISP isn't all that familiar to me). The doubling of the region message is probably tied to another minor issue, i.e. when you select an invalid boundary (like one enclosed by a spline) then get the above error message, it repeats the previous successful offset you performed. So in my case, I'm offsetting these things by 2.5mm, then when I get this error message, the last individual boundary I offset is then offset to 5mm.

3) It would be great to be able to undo while the command is active if you screw up while selecting an internal point, or if a boundary you think is closed is actually open. As it stands, you have to exit the command then delete the accidental offset, then start the command again.

 

All of the above are basically just details though. The thing is 100% usable notwithstanding, and like I said, saved me hours and hours of time. So regardless of whether you want to spend the time tweaking the above stuff, the thing's great and I can't thank you enough for it.

 

0 Likes

Right, sorry, yeah, it works marvelously. Saved me legitimately hours of time on this project. Couple of minor notes:

1) It would be perfect if this worked with splines, but I personally work with them pretty rarely so for me this isn't that big of a deal

2) When trying to form a boundary with at least one side being a spline, the following sequence of events happens: 1) Select boundaries, 2) Specify internal point, 3) This is where weird stuff happens. First, a new line in the command window comes up saying "Polyline boundary could not be derived. Create Region? <Y> Polyline boundary could not be derived. Create Region? <Y>" - note the <Y> indicates the default option, not the choice specified by the user, and both of these appear at once on the same line ("line" here referring to the command line, not a line object in the drawing). Additionally, the previous line instead of saying "Specify internal point" as it did when originally prompting you, now says "Specify internal point or [Advanced options]". Example:

 

 

Capture4.PNG

 

The "Advanced options" thing isn't visible or accesible when you're actually being prompted to specify the internal point, and appears to be a side-effect of whatever intermediate magic this script is performing, since I don't see it anywhere in the code (though LISP isn't all that familiar to me). The doubling of the region message is probably tied to another minor issue, i.e. when you select an invalid boundary (like one enclosed by a spline) then get the above error message, it repeats the previous successful offset you performed. So in my case, I'm offsetting these things by 2.5mm, then when I get this error message, the last individual boundary I offset is then offset to 5mm.

3) It would be great to be able to undo while the command is active if you screw up while selecting an internal point, or if a boundary you think is closed is actually open. As it stands, you have to exit the command then delete the accidental offset, then start the command again.

 

All of the above are basically just details though. The thing is 100% usable notwithstanding, and like I said, saved me hours and hours of time. So regardless of whether you want to spend the time tweaking the above stuff, the thing's great and I can't thank you enough for it.

 

Message 8 of 10
Moshe-A
in reply to: Anonymous

Moshe-A
Mentor
Mentor

@Anonymous ,

 

Yeah you are right it's fail with splines although i initially 'design' it to work with splines.

by default BPOLY draws boundary by pline but when a spline is involves it want's to switch to region so this is the spot it fails. say i would accept that (the region), right after i would have face another issue...OFFSET can not offset a region. so the solution was to convert the spline to pline preform the offset and quickly remove the unneeded stuff.

 

i added an undo feature but this required me the switch prompts:

 

Specify internal point or [Undo]:           {first prompt}

Specify candidate set for boundary...    {second prompt}
Select objects: 

 

obvious, undo will take you one step back due to that the overall undo is not maintained, this means if you exit normally from BOFFSET and take one U, only the last offset is removed.

 

enjoy

moshe

 

 

(vl-load-com) ; load activex support

(defun c:boffset (/ askOffset askpoint spline_convert ; local functions
		    ofset ctr ss0 ss1 p0 AcDbPolyline)
  
 (defun askOffset (msg def / ask)
  (initget 2)
  (if (not (setq ask (getdist (strcat "\n" msg " <" (rtos def 2) ">: "))))
   (setq ask def)
   (setq def ask)
  )
 ); askOffset
  
 (defun askpoint (/ flag ask)
  (setq ask "")
  (setvar "blipmode" 1)
   
  (while (eq (type ask) 'STR)
   (cond
    ((= ctr 0)
     (setq ask (getpoint "\nSpecify internal point: "))
    ); case
    ( t
     (initget "Undo")
     (setq ask (getpoint "\nSpecify internal point or [Undo]: "))
     (if (eq ask "Undo")
      (progn
       (command "._undo" 1)
       (setvar "blipmode" 1)
       (setq ctr (1- ctr))
      ); progn
     ); if
    ); case
   ); cond
  ); while

  (setvar "blipmode" 0)
  ask  
 ); askpoint
  
 (defun spline_convert (/ ss2 i ename0 ename1)
  (if (setq ss2 (ssget "p" '((0 . "spline"))))
   (progn
    (command-s "._copy" "_si" ss2 "_none" "0,0,0" "_none" "0,0,0")
    (setq i -1 ss1 (ssadd))
    (repeat (sslength ss2)
     (setq ename0 (ssname ss2 (setq i (1+ i)))) 
     (command-s "._splinedit" "_none" ename0 "_P" "")
     (ssdel ename0 ss0)
     (setq ename1 (entlast))
     (ssadd ename1 ss0)
     (ssadd ename1 ss1)
    ); repeat
   ); progn
  ); if
 ); spline_convert
  
 ; here starts c:boffset
 (setvar "cmdecho" 0)
 (if (= (getvar "userr1") 0.0)
  (setq ofset 10.0)
  (setq ofset (getvar "userr1"))
 )

 (setvar "userr1" (setq ofset (askOffset "Specify offset distance" ofset)))

 (setq ctr 0) 
 (while (and
	  (setq p0 (askpoint))
          (not (prompt "\nSpecify candidate set for boundary..."))
          (setq ss0 (ssget '((0 . "*line,arc,circle,ellipse"))))
        )
  (vla-startUndoMark (vla-get-activedocument (vlax-get-acad-object))) 
  (setq ctr (1+ ctr)) 
  (spline_convert)
  (command-s "._bpoly" "_Advanced" "_Boundary" "_New" "si" ss0 "" "_none" p0 "")
  (setq AcDbPolyline (vlax-ename->vla-object (entlast))) ; allocating memory
  (vla-offset AcDbPolyline (* -1 ofset))
  (vla-delete AcDbPolyline)
  (vlax-release-object AcDbPolyline) ; dispose memory
  ; delete copied polylines
  (if (and ss1 (> (sslength ss1) 0))
   (command-s "._erase" "_si" "_none" ss1)
  )
  (vla-endUndoMark (vla-get-activedocument (vlax-get-acad-object)))
 ); while

 (setvar "cmdecho" 1)
 (princ)  
); c:boffset

0 Likes

@Anonymous ,

 

Yeah you are right it's fail with splines although i initially 'design' it to work with splines.

by default BPOLY draws boundary by pline but when a spline is involves it want's to switch to region so this is the spot it fails. say i would accept that (the region), right after i would have face another issue...OFFSET can not offset a region. so the solution was to convert the spline to pline preform the offset and quickly remove the unneeded stuff.

 

i added an undo feature but this required me the switch prompts:

 

Specify internal point or [Undo]:           {first prompt}

Specify candidate set for boundary...    {second prompt}
Select objects: 

 

obvious, undo will take you one step back due to that the overall undo is not maintained, this means if you exit normally from BOFFSET and take one U, only the last offset is removed.

 

enjoy

moshe

 

 

(vl-load-com) ; load activex support

(defun c:boffset (/ askOffset askpoint spline_convert ; local functions
		    ofset ctr ss0 ss1 p0 AcDbPolyline)
  
 (defun askOffset (msg def / ask)
  (initget 2)
  (if (not (setq ask (getdist (strcat "\n" msg " <" (rtos def 2) ">: "))))
   (setq ask def)
   (setq def ask)
  )
 ); askOffset
  
 (defun askpoint (/ flag ask)
  (setq ask "")
  (setvar "blipmode" 1)
   
  (while (eq (type ask) 'STR)
   (cond
    ((= ctr 0)
     (setq ask (getpoint "\nSpecify internal point: "))
    ); case
    ( t
     (initget "Undo")
     (setq ask (getpoint "\nSpecify internal point or [Undo]: "))
     (if (eq ask "Undo")
      (progn
       (command "._undo" 1)
       (setvar "blipmode" 1)
       (setq ctr (1- ctr))
      ); progn
     ); if
    ); case
   ); cond
  ); while

  (setvar "blipmode" 0)
  ask  
 ); askpoint
  
 (defun spline_convert (/ ss2 i ename0 ename1)
  (if (setq ss2 (ssget "p" '((0 . "spline"))))
   (progn
    (command-s "._copy" "_si" ss2 "_none" "0,0,0" "_none" "0,0,0")
    (setq i -1 ss1 (ssadd))
    (repeat (sslength ss2)
     (setq ename0 (ssname ss2 (setq i (1+ i)))) 
     (command-s "._splinedit" "_none" ename0 "_P" "")
     (ssdel ename0 ss0)
     (setq ename1 (entlast))
     (ssadd ename1 ss0)
     (ssadd ename1 ss1)
    ); repeat
   ); progn
  ); if
 ); spline_convert
  
 ; here starts c:boffset
 (setvar "cmdecho" 0)
 (if (= (getvar "userr1") 0.0)
  (setq ofset 10.0)
  (setq ofset (getvar "userr1"))
 )

 (setvar "userr1" (setq ofset (askOffset "Specify offset distance" ofset)))

 (setq ctr 0) 
 (while (and
	  (setq p0 (askpoint))
          (not (prompt "\nSpecify candidate set for boundary..."))
          (setq ss0 (ssget '((0 . "*line,arc,circle,ellipse"))))
        )
  (vla-startUndoMark (vla-get-activedocument (vlax-get-acad-object))) 
  (setq ctr (1+ ctr)) 
  (spline_convert)
  (command-s "._bpoly" "_Advanced" "_Boundary" "_New" "si" ss0 "" "_none" p0 "")
  (setq AcDbPolyline (vlax-ename->vla-object (entlast))) ; allocating memory
  (vla-offset AcDbPolyline (* -1 ofset))
  (vla-delete AcDbPolyline)
  (vlax-release-object AcDbPolyline) ; dispose memory
  ; delete copied polylines
  (if (and ss1 (> (sslength ss1) 0))
   (command-s "._erase" "_si" "_none" ss1)
  )
  (vla-endUndoMark (vla-get-activedocument (vlax-get-acad-object)))
 ); while

 (setvar "cmdecho" 1)
 (princ)  
); c:boffset

Message 9 of 10
Moshe-A
in reply to: Anonymous

Moshe-A
Mentor
Mentor
Accepted solution

during a night had some doubts on what i did regarding Undo and made more changes so now it works better including the overall undo.

 

the file is attach for your convenient.

 

moshe

 

during a night had some doubts on what i did regarding Undo and made more changes so now it works better including the overall undo.

 

the file is attach for your convenient.

 

moshe

 

Message 10 of 10
Anonymous
in reply to: Moshe-A

Anonymous
Not applicable

Wunderbar! Danke schon, will give this a spin and let you know how it goes ASAP. Afraid it might be another day or two as it's for a gift whose recipient is currently in eyeshot of the monitor, but I'll find some time to give it a spin 😉

 

vIf0lAD.gif

0 Likes

Wunderbar! Danke schon, will give this a spin and let you know how it goes ASAP. Afraid it might be another day or two as it's for a gift whose recipient is currently in eyeshot of the monitor, but I'll find some time to give it a spin 😉

 

vIf0lAD.gif

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report