AutoLISP: Fillet and Match PLINE Width

With the release of AutoCAD 2012 the JOIN command received some improvements. It will join all of the selected objects regardless of what type of objects they are (line, arc, polyline, 3Dpolyline, spline) and turn them into the most complicated object in the selection set. Because of this enhancement of the JOIN command, it appears that Autodesk took away a useful feature from the FILLET command. The missing feature that many are used to seeing is when you fillet a polyline that has  a width applied to it, the other objects would inherit the width of the polyline. This is no longer the case with the FILLET command in 2012 and 2013.

Luckily I found this routine that lets you FILLET objects just like before…

originally found here:

Fillet Behavior introduced in AutoCAD 2012:

Fillet 2012Fillet behavior prior to 2012 and that the lisp routine provides:

My Fillet New



;;; MY-FILLET.LSP Fillet PolyLines
;;; Fillets Any Type of Line (Line, PolyLine, LWPolyLine or Spline)
;;; by Ibro Vehabovic, March 1999.

(defun c:my-fillet (/ getval spl2pl e1 e2 p2 l e ss)

;;; GETVAL - returns the group value of an entity.
;;; like the wellknown (dxf) function but accepts all kinds of
;;; entity representations (ename, entget list, entsel list)
  (defun GETVAL	(grp ele)		;"dxf value" of any ent...
    (cond ((= (type ele) 'ENAME)	;ENAME
	   (cdr (assoc grp (entget ele)))
	  ((not ele) nil)		;empty value
	  ((not (listp ele)) nil)	;invalid ele
	  ((= (type (car ele)) 'ENAME)	;entsel-list
	   (cdr (assoc grp (entget (car ele))))
	  (T (cdr (assoc grp ele)))
  )					;entget-list

;;; "converts" SPLINE to PLINE
  (defun spl2pl	(ent / osm pdm deltaL pn pts e)
    (setq osm (getvar "OSMODE"))
    (setq pdm (getvar "PDMODE"))
    (setvar "OSMODE" 0)
    (setvar "PDMODE" 0)
      deltaL (*	(/ (GETVAR "viewsize") (CADR (GETVAR "screensize")))
		(getvar "pickbox")
    )					; max segment=2 * size of
    (if	(= (getval 0 ent) "POLYLINE")	; heavy pline
	(setq e ent)
	(while (= (getval 0 (setq e (entnext e))) "VERTEX")
	  (setq pts (cons (getval 10 e) pts))
	(setq pn  (car pts)
	      pts (list (last pts))
      (setq pts	(list (getval 10 ent))	; start pt
	    pn	(getval 10 (reverse (entget ent)))
    )					; end pt
    (command ".POINT" pn)
    (setq e (entlast))
    (entdel e)
    (command ".AREA" "_O" ent)
    (command ".DIVIDE"
	     (fix (/ (getvar "perimeter") deltaL))
    (while (setq e (entnext e))
      (setq pts (cons (getval 10 e) pts))
      (entdel e)
    (setq pts (reverse (cons pn pts)))
    (apply 'command (append '(".PLINE") pts '("")))
    (command ".CHANGE"
	     (getval 8 ent)
    (if	(getval 62 ent)
      (command ".CHANGE"
	       (getval 62 ent)
    (entdel ent)
    (setvar "PDMODE" pdm)
    (setvar "OSMODE" osm)
  )					;defun spl2pl

  (setvar "cmdecho" 0)
  (command "._UNDO" "_BE")
  (while (null (setq e1 (entsel "\nSelect first object: "))))
  (if (= (getval 0 e1) "SPLINE")
    (setq e1 (list (spl2pl (car e1)) (cadr e1)))
  (if (= (getval 0 e1) "POLYLINE")
    (if	(> (getval 70 e1) 1)
      (setq e1 (list (spl2pl (car e1)) (cadr e1))) ;fit or spline
      (command ".CONVERTPOLY" "_L" (car e1) "")
  )					;heavy pline
  (redraw (car e1) 3)
  (while (null (setq e2 (entsel "\nSelect second object: "))))
  (if (= (getval 0 e2) "SPLINE")
    (setq e2 (list (spl2pl (car e2)) (cadr e2)))
  (if (= (getval 0 e2) "POLYLINE")
    (if	(> (getval 70 e2) 1)
      (setq e2 (list (spl2pl (car e2)) (cadr e2))) ;fit or spline
      (command ".CONVERTPOLY" "_L" (car e2) "")
  )					;heavy pline
  (redraw (car e2) 3)
  (setq p2 (cadr e2))
  (setq e2 (car e2))
  (if (and (= (getval 0 e1) "LWPOLYLINE")
	   (= (getval 0 e2) "LWPOLYLINE")
      (setq l (entlast))
      (command ".EXPLODE" e2)
      (setq ss (ssadd))
      (ssadd (setq e (entnext l)) ss)
      (while (setq e (entnext e))
	(ssadd e ss)
      (command ".FILLET" e1 (nentselp p2))
      (command ".PEDIT" e1 "_J" ss "" "") ; join
      (command ".ERASE" ss "")		; erase unjoined segments
					; of the second polyline
    )					;progn
    (command ".FILLET" e1 (nentselp p2)) ;normal fillet
  )					;if
  (command "._UNDO" "_E")
)					;defun

About AutoCAD Tips

This blog serves as a knowledge base for myself (and anyone else) so that I can reference tips & tricks that I have learned and also refer others to it as well. I hope that this blog helps you learn at least one tip to make your drafting/design experience better.
This entry was posted in AutoCAD 2013, AutoLISP, AutoLISP: Modify, AutoLISP: Polylines, Modifying, New in 2012, New In 2013, Polylines. Bookmark the permalink.

4 Responses to AutoLISP: Fillet and Match PLINE Width

  1. AutoCAD Tips says:

    Good point
    Below is a link to a routine that lets you offset segments of a polyline without exploding

  2. stephen h says:

    thanks for posting this. I cannot for the life of me see why Autodesk deprecated the fillet method this way! it ALWAYS means an extra step to drawing, and at least in my methods there is never a reason to maintain a 0 width from the line source!

  3. Jan K says:

    The same annoying change in fillet behavior showed up in AutoCAD Lt 2012. Unfortunately, you can’t run lisp routines in Lt.

  4. stephen h says:

    not to worry. we’ll see it “introduced” as a great improvement to the fillet command, some time in the future, by autodesk. but great, absolutely great, to have this replacement.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s