Fillet polyline with arc not working

Fillet polyline with arc not working

eakos1
Advocate Advocate
330 Views
11 Replies
Message 1 of 12

Fillet polyline with arc not working

eakos1
Advocate
Advocate

If a polyline ended in an arc it is not possible make the fillet with an arc, it gives always the respond: Cannot fillet between these two entities. This is very annoying, we have to do it very often. 


Just an example. 

eakos1_0-1757083876674.png

Even if I draw two arcs but one of them is polyline the fillet isn't working. 

eakos1_1-1757084250670.png

 



Do someone wrote a lisp for it? I tried to find on the net but with no result. 

 

0 Likes
331 Views
11 Replies
Replies (11)
Message 2 of 12

Kent1Cooper
Consultant
Consultant

This has always been a limitation.  Until they decide to change that, it's a little less immediate, but EXTEND and TRIM can get you where you want to go [including the appropriate Edge-extension setting].  If you need a non-zero Fillet radius, you can achieve that with CIRCLE's Tangent-Tangent-Radius option and then some Trimming.  Or if there are no widths involved [as there are not in your examples], you can EXPLODE a Polyline, do the FILLET operation(s), and rejoin the results into a Polyline again.

[But no, I don't have anything like a routine to offer.]

Kent Cooper, AIA
0 Likes
Message 3 of 12

eakos1
Advocate
Advocate

I've just made the code myself.
After selection of a LWPOLYLINE you can select a LINE/ARC/LWPOLYLINE and the program can make the fillet, finally the program join them to one polyline. 

 

0 Likes
Message 4 of 12

CADaSchtroumpf
Advisor
Advisor

Wouldn't it be easier to do the opposite instead of EXPLODE to JOIN later, make rather a PEDIT on Arc or Line?

Example:

(defun C:fillet_pline&line ( / ss1 ent1 pt_sel1 ss2 ent2 typ_ent pt_sel2)
  (princ "\nSelect a LWPOLYLINE: ")
  (while
    (not
      (setq ss1
        (ssget "_+.:E:S"
          (list
            (cons 0 "*POLYLINE")
            (cons -4 "<NOT")
              (cons -4 "&") (cons 70 112)
            (cons -4 "NOT>")
          )
        )
      )
    )
  )
  (setq
    ent1 (ssnamex ss1 0)
    pt_sel1 (cadar (cdddar ent1))
  )
  (princ "\nSelect a LINE/ARC/LWPOLYLINE: ")
  (while
    (not
      (setq ss2
        (ssget "_+.:E:S"
          (list
            (cons -4 "<AND")
              (cons 0 "*POLYLINE,LINE,ARC")
              (cons -4 "<NOT")
                (cons -4 "&") (cons 70 112)
              (cons -4 "NOT>")
            (cons -4 "AND>")
          )
        )
      )
    )
  )
  (setq
    ent2 (ssnamex ss2 0)
    typ_ent (cdr (assoc 0 (entget (cadar ent2))))
    pt_sel2 (cadar (cdddar ent2))
  )
  (cond
    ((member typ_ent '("LINE" "ARC"))
      (command "_.pedit" pt_sel2 "_yes" "")
    )
  )
  (command "_.fillet" pt_sel1 pt_sel2)
  (prin1)
)
0 Likes
Message 5 of 12

Sea-Haven
Mentor
Mentor

The issue of FILLET not working has been in Acad since it first came out. A simple example is two arcs add a third arc in between the two arcs by using fillet, It often draws a "S". Other software has purpose written programs to get around this problem, they existed back in the 80's. As suggested by @Kent1Cooper using the Circle TTR option is often the only way to get a result. Bottom is original two arcs, middle is circle TTR, top is fillet.

 

 

SeaHaven_0-1757378942129.png

 

@CADaSchtroumpf tried code and got an error I use Bricscad normally.

(setq
    ent1 (ssnamex ss1 0)
    pt_sel1 (cadar (cdddar ent1))
  )

; ----- Error around expression -----
; (CDDDAR ENT1)
;
; error : bad argument type <-1> ; expected <CONS> at [cdr]

 

 

 

0 Likes
Message 6 of 12

eakos1
Advocate
Advocate

This code is very simple but not works well, because not considers which side is the start and end point of the polyline, and it doesn't matter. 

I've mad for me 4 possible combinations. 

eakos1_0-1757396925415.png

Your code make the fillet in certain cases the wrong way. So I think there is no other way, always should be checked were is the selection point and the relative positions of the to polylines.  

eakos1_1-1757396974628.png        eakos1_2-1757397014286.png

 

    

 

 

0 Likes
Message 7 of 12

komondormrex
Mentor
Mentor

@eakos1 

have you tried that simple one

(command "_fillet" "_t" "_t" pause pause)

 

0 Likes
Message 8 of 12

eakos1
Advocate
Advocate

Not always works.

 

eakos1_0-1757489223331.png    eakos1_1-1757489250803.png

 

But intresting, in case of polyline this simple code not works, only with ARC and LINE. 

My idea was to draw the fillet without trim and with entlast get the name and with trim just trim the polylines. But in case of polylines not draws the arc. 

(setq a (entsel))
(setq b (entsel))
(command "_fillet" "_t" "_n" a b )

(entlast)

(trim ......)

 

 

0 Likes
Message 9 of 12

komondormrex
Mentor
Mentor

which version of autocad do you use? in 26 there is the only pair when fillet doesn't come when you filleting an arc with pline's line segment. other pairs fillet okay.

komondormrex_0-1757526227780.png

komondormrex_1-1757526342102.pngkomondormrex_2-1757526393143.png

komondormrex_3-1757526525299.png

 

 

 

0 Likes
Message 10 of 12

Sea-Haven
Mentor
Mentor

Re new arc is upside down found this today for something else, if using Circle TTR picking clockwise or anticlockwise will draw in the two different directions. Does not work for plain Fillet command. 

 

0 Likes
Message 11 of 12

eakos1
Advocate
Advocate

I use AutoCAD 2015

0 Likes
Message 12 of 12

Moshe-A
Mentor
Mentor

@eakos1  hi,

 

Check this curveJoin command. it is based on CIRCLE TTR command.

this version refers to the 2 selected objects as curves (covers 2dpolylines, lines, arcs)

instead of exploding the curves, it adds a connecting arc on the current layer and the curves are not joined,

i leave that for you. as i understand, fillet radius is not that important here but TTR requires a radius so...

to figure a suitable, first draw a CIRCLE 2P between the 2 curves to get a close radius.

 

CIRCLE TTR is done on a temporary layer set to off so user does not see behind the scenes 😀

this layer is than purged.

 

make sure you pick the curves close to the end that should be trimmed. if on the first try you get wrong result,

try again and swap your picks.

 

enjoy

Moshe

 

;;; curvejoin.lsp
;;; by Moshe-A
;;; SEP 12, 2025


;; Intersections  -  Lee Mac
;; Returns a list of all points of intersection between two objects
;; for the given intersection mode.
;; ob1,ob2 - [vla] VLA-Objects
;;     mod - [int] acextendoption enum of intersectwith method

(defun LM:intersections ( ob1 ob2 mod / lst rtn )
    (if (and (vlax-method-applicable-p ob1 'intersectwith)
             (vlax-method-applicable-p ob2 'intersectwith)
             (setq lst (vlax-invoke ob1 'intersectwith ob2 mod))
        )
        (repeat (/ (length lst) 3)
            (setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn)
                  lst (cdddr lst)
            )
        )
    )
    (reverse rtn)
); LM:intersections


; Special fillet
(defun c:curveJoin (/ _select_object _askdist _swapVar _picked_side _get_close_cross _purge_temp_layer	; local functions
		      MA:DICTAPPNAME MA:DATAPROP MA:TEMPLAY						; local variables
		      defrad frad currLayer pick0 pick1 ename0 ename1 ename2 cr0^ cr1^			; local variables
		      AcDbCurve0 AcDbCurve1 AcDbCurve2 p0 p1 t0 t1 c0 crad sa ea)			; local variables

 ;                           argument by reference
 (defun _select_object (step Qpick Qename / pick ename elist flag)
  (while (and (not flag)
	      (setq pick (entsel (strcat "\nPick " step " curve: ")))
	 )
   (cond
    ((not
       (and
        (setq ename (car pick))
        (setq elist (entget ename))
        (wcmatch (cdr (assoc '0 elist)) "LINE,ARC,LWPOLYLINE")
       )
     )
     (vlr-beep-reaction)
     (prompt "\nInvalid selected curve.")
    ); case
    ( t
     (set Qpick pick)   ; indirect set
     (set Qename ename) ; indirect set
     (setq flag t)
    ); case
   ); cond
  ); while

  flag
 ); select_object


 (defun _askdist (msg def / ask)
  (initget (+ 2 4))
  (if (not (setq ask (getdist (strcat "\n" msg " <" (rtos def) ">: "))))
   (setq ask def)
   (setq def ask)
  ); if
 ); _askdist

  
 (defun _swapVar (Qa0 Qa1 / tmp)
  (setq tmp (vl-symbol-value Qa0))
  (set  Qa0 (vl-symbol-value Qa1))
  (set  Qa1 tmp)
 ); _swapVar


 (defun _picked_side (ename pt / prm0 prm1 prmX)
  (setq prm0 (vlax-curve-getStartParam ename))
  (setq prm1 (vlax-curve-getEndParam ename))
  (setq prmX (vlax-curve-getParamAtPoint ename (vlax-curve-getClosestPointTo ename pt)))
  (if (< (- prmX prm0) (- prm1 prmX))
   (vlax-curve-getStartPoint ename)
   (vlax-curve-getEndPoint   ename)
  ); if
 ); _picked_side

  
 ; return the close crossing point to picked point
 (defun _get_close_cross (ename base cross^ / basePrm )
  (setq basePrm (vlax-curve-getparamAtPoint ename base))
   
  (cadar
   (vl-sort
    (mapcar
     (function
      (lambda (cr / prm)
       (setq prm (vlax-curve-getparamAtPoint ename cr))
       (list (if (> prm basePrm) prm (- basePrm prm)) cr)
      ); lambda 
     ); function
     cross^
    ); mapcar
    (function (lambda (e0 e1) (< (car e0) (car e1))))
   ); vl-sort
  ); cadar
 ); _get_close_cross


 (defun _purge_temp_layer (/ layers AcDblayerTableRec)
  (setq layers (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))

  (setq AcDblayerTableRec (vla-item layers MA:TEMPLAY))
  (vla-delete AcDblayerTableRec)
   
  (vlax-release-object AcDblayerTableRec)
  (vlax-release-object layers)
 ); _purge_layer

  
 ; here start c:curveJoin
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")

 (setq MA:DICTAPPNAME "curveJoin.lsp-by-Moshe-A-SEP2025")
 (setq MA:DATAPROP "radius")
 (setq MA:TEMPLAY "$curveJoin")

 (if (not (vlax-ldata-get MA:DICTAPPNAME MA:DATAPROP))
  (setq defrad (vlax-ldata-put MA:DICTAPPNAME MA:DATAPROP (getvar "filletrad")))
  (setq defrad (vlax-ldata-get MA:DICTAPPNAME MA:DATAPROP))
 )
   
 (cond
  ((not (_select_object "1st" 'pick0 'ename0)))
  ((not (_select_object "2nd" 'pick1 'ename1)))
  ((setq frad (_askdist "Specify fillet radius" defrad))

   (setq currLayer (getvar "clayer")) ; save working layer

   ; prepare temporary layer for temp geometry, set to off
   (if (null (tblsearch "layer" MA:TEMPLAY))
    (command "._layer" "_make" MA:TEMPLAY "_Off" MA:TEMPLAY "_Yes" "")
    (command "._layer" "_Set" MA:TEMPLAY "_Off" MA:TEMPLAY "_Yes" "")
   ); if
     
   (command "._circle" "_ttr" (cadr pick0) (cadr pick1) "_None" frad)
   (setq ename2 (entlast))
   (command "._extend" "_None" ename2 "" "_None" pick0 "_None" pick1 "")
   
   (setq AcDbCurve0 (vlax-ename->vla-object ename0))
   (setq AcDbCurve1 (vlax-ename->vla-object ename1))
   (setq AcDbCurve2 (vlax-ename->vla-object ename2))
   
   (if (and
	 (setq cr0^ (LM:intersections AcDbCurve0 AcDbCurve2 acExtendNone)) ; may return more than 1 point
         (setq cr1^ (LM:intersections AcDbCurve1 AcDbCurve2 acExtendNone)) 
       )
    (progn
     (setq p0 (_picked_side ename0 (cadr pick0))) ; 1st start point close to picked point
     (setq p1 (_picked_side ename1 (cadr pick1))) ; 2nd start point close to picked point

     (setq t0 (_get_close_cross ename0 p0 cr0^))  ; 1st tanget point
     (setq t1 (_get_close_cross ename1 p1 cr1^))  ; 2nd tanget point

     ; circle center point
     (setq c0 (vlax-safearray->list (vlax-variant-value (vla-get-center AcDbCurve2))))
     (setq crad (vla-get-radius AcDbCurve2))      ; circle radiius
     (setq sa (angle c0 t0)) ; arc start angle
     (setq ea (angle c0 t1)) ; arc end   angle

     (if (< ea sa)
      (progn
       ; swap data
       (_swapVar 'ea 'sa)
       (_swapVar 'p0 'p1)
       (_swapVar 't0 't1)
       (_swapVar 'ename0 'ename1)
      ); progn
     ); if

     (setvar "clayer" currLayer) ; restore working layer
     (command "._arc" "_None" t0 "_C" "_None" c0 "_None" t1) ; connecting arc
     (entdel ename2) ; delete circle
     (_purge_temp_layer)

     ; trim selected curves
     (command "._break" "_None" (list ename0 t0) p0)
     (command "._break" "_None" (list ename1 t1) p1)
     
     ; dispose memory
     (vlax-release-object AcDbCurve2)
     (vlax-release-object AcDbCurve1)
     (vlax-release-object AcDbCurve0)

     ; save in dictionary sapce as default
     (vlax-ldata-put MA:DICTAPPNAME MA:DATAPROP frad)
    ); progn
   ); if
   
  ); case
 ); cond

 (command "._undo" "_end")
 (setvar "cmdecho" 1)

 (princ)
); c:curveJoin

 

0 Likes