Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

master fillet lisp

29 REPLIES 29
Reply
Message 1 of 30
barry2104
6052 Views, 29 Replies

master fillet lisp

I'm looking for a lisp which ultimately is a one-stop-shop for filleting and contains the following features/abilities:

 

1) If i have a polyline in the shape of a P (that is, not a "closed" polyline), I cannot currently use fillet to turn the P into a (closed) D shape. Instead I have to trim, because if i try the fillet command, I need to click on two separate entities and this is a single-entity polyline so it can't work here without a lisp perhaps. Is this possible?

2) I'd like to be able to fillet two lines which have differing z-values. The default fillet command is limited working only when the two filleted elements are in the same plane. An extra query in this lisp asking me "these two elements have different z-values... enter desired z-value for polyline" would be good (though even better if it only asked that when the two elements ARE non-planar, which is only 5% of the time - i.e. ideally I don't get prompted for this every time I fillet, rather, just when the elements aren't in the same plane).

 

3) normally the resultant polyline assumes the layer of the first selected line, though sometimes (not sure why/when) it plays up and no matter which line i select first, the layer is not the one I want. If this click-priority could be written into the lisp too, that would solve this glitch for me

 

4) FILLET command only assumes LAYER name & colour, but not global width of the first line/element picked. It would be handy to be able to join the first polyline (global width = 0.5) to a line (no global width) and have the resultant 3-node polyline have a global width of 0.5

 

5) being able to fillet non-standard elements (e.g. spline) would be a bonus i suppose, but I so rarely use this that it's perhaps not worth the effort. Instead for these cases I could always turn the spline into a polyline (using the FLATTEN command) and then use the regular Fillet command to join them up... though I imagine these steps could be worked into this master-lisp relatively easily?

 

if anyone knows of a lisp to do this, or has the smarts to create one to integrate as many/all of these asks as possible, that would be amazeballs.

 

cheers!

Running AutoCAD Architecture 2020, in German
Tags (2)
29 REPLIES 29
Message 2 of 30
bgingerich
in reply to: barry2104

1)  This should work for a "P" to "D" shape.  Not sure if this is what you were looking to do? (untested w/ no error handling)

(defun C::new_fillet (/ ent point1 point2 pl)
	(setq point1 (cdr (setq ent (entsel "\nPick first side to fillet: ")))
		point2 (cdr (entsel "\nPick second side to fillet: "))
		pl (car ent)
	);_ end of setq
	(command "_.pedit" ent "close" "")
	(command "_.fillet" point1 point2)
    (princ) );_ end of defun

 

(if ("mysolution"=answer) then (click "Accept As Solution"))
------------------------------------------------------------------------------------

─────────────────────────────────────────────────────────────────────────────────────────────
Brandon Gingerich
Message 3 of 30
barry2104
in reply to: bgingerich

thanks for the response, but the code doesn't seem to work (at least not for me!).

 

If anyone else has tips/solutions to integrate as many of the aforementioned functions into the one lisp as possible, I'd love to hear from you!!

Running AutoCAD Architecture 2020, in German
Message 4 of 30
Kent1Cooper
in reply to: barry2104


@barry2104 wrote:

thanks for the response, but the code doesn't seem to work (at least not for me!).

....


Try this adjusted version:
 

(defun C:new_fillet (/ ent point1 point2 pl); single colon
  (setq
    point1 (cadr (setq ent (entsel "\nPick first side to fillet: "))); point, rather than list containing point
    point2 (cadr (entsel "\nPick second side to fillet: "))
    pl (car ent)
  );_ end of setq
  (command "_.pedit" ent "close" "")
  (command "_.fillet" point1 point2)
  (princ)
);_ end of defun

 

EDIT:  HOWEVER, that works only if the P has a line segment at the base of the "loop" part, ending on the "stem" line segment, and if you select on that line segment at the base of the loop, not on the arc segment that loops.  If it's just a vertical stem and an arc segment ending into it, it does close it, but doesn't do what you're looking for.  And if it has the line segment at the base of the loop, but you pick on the arc segment beyond that, it fails because you can't Fillet arc segments in Polylines, and also there will be two intervening segments between the selected ones.

Kent Cooper, AIA
Message 5 of 30
barry2104
in reply to: Kent1Cooper

Thanks ken, but this still doesn't seem to work either!

I've attached a before & after jpg to show what I effectively want to do. I have an open polyline that I want to fillet to close it. So i type in this magical lisp shortcut and it asks me to pick the two lines to fillet (can be two separate lines/polylines or even both along the same polyline), so i click at the red points 1 and 2.
Then, heypresto, result shown on the right!

 

^this describes the solution to feature #1... features number 2 and 4 are also of high importance so if either/both of these respective codes/lisps could be worked into the one file that would be rad

 

any input appreciated!

Running AutoCAD Architecture 2020, in German
Message 6 of 30
Kent1Cooper
in reply to: barry2104


@barry2104 wrote:

Thanks ken, but this still doesn't seem to work either!

I've attached a before & after jpg to show what I effectively want to do. ....


It works for me with a P of the right characteristics, but as for you, doesn't work in your illustrated situation.  I suspected at first that it's probably because the closed Polyline that the routine brings about on the way to Filleting is self-intersecting.  But it works [for me] with such a Polyline if there are more than three segments.  Then I guessed that since Fillet with 0 radius on a Polyline works by eliminating one intermediate segment between those picked, in this case it's trying to fillet out the upper-right-edge segment that's intermediate between them in the Polyline's vertex sequence, but because of the directions of things, it can't do that, and it isn't smart enough to look at the other side for a single intermediate segment.  And yet it does work if a three-segment Polyline is not self-intersecting to begin with, in which case it is finding that other-side intermediate segment.  It must be something in the combination of three segments and self-intersection.

 

If you're always doing this with Polylines of only line segments, I can imagine a way to do it:

 

Find the crossing point [or virtual crossing point if it isn't already self-intersecting] with the (...intersectwith...) VLA method.

Pedit the Polyline to move its starting vertex to that crossing point, remove its last segment, and close it.

 

But that won't always give you the right result if there are arc segments involved.

Kent Cooper, AIA
Message 7 of 30
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:
....

Try this adjusted version:
 

(defun C:new_fillet (/ ent point1 point2 pl); single colon
  (setq
....

    pl (car ent)
  );_ end of setq
  (command "_.pedit" ent "close" "")
....


And another thing:

 

(defun C:new_fillet (/ ent point1 point2);;; pl not used); single colon
  (setq
    point1 (cadr (setq ent (entsel "\nPick first side to fillet: "))); point, rather than list containing point
    point2 (cadr (entsel "\nPick second side to fillet: "))
;;;    pl (car ent);;; not used
  );_ end of setq
  (command "_.pedit" ent "close" "");;; or, keep pl variable above and use here in place of ent
  (command "_.fillet" point1 point2)
  (princ)
);_ end of defun

Kent Cooper, AIA
Message 8 of 30
barry2104
in reply to: Kent1Cooper

thanks for your efforts Ken, but I think request-function #1 is a lost cause.

 

Any idea how to crack functions 2 and/or 4 described in the original post?
#2 is effectively giving both entities a z-value of zero before applying the fillet (in case they weren't already at z=0)

#4 is to do a match-properties from the first entity to the second (including global width etc) as it gets filleted

Running AutoCAD Architecture 2020, in German
Message 9 of 30
Kent1Cooper
in reply to: barry2104


@barry2104 wrote:

thanks for your efforts Ken, but I think request-function #1 is a lost cause.

....


Not so fast....

 

The following works at the moment only for a 3-segment-only line-segment-only lightweight-only Polyline, which in that case you need to select only once, and it closes it whether self-intersecting as in your image or not.  Compensations can be made for other possibilities ["heavy" 2D or 3D Polylines, more than 3 segments, etc.], but the principle is there.

 

(defun C:FF (/ plent plobj vertc intc vertpt vertpts intpt done)

  (setq
    plent (car (entsel "\nSelect open Polyline to fillet/close: "))
    plobj (vlax-ename->vla-object plent)
    vertc (safearray-value (variant-value (vla-get-Coordinates plobj))); VERTex Coordinates
    intc (safearray-value (variant-value (vla-IntersectWith plobj plobj acExtendBoth))); INTersection Coordinates
      ; for both on same Pline; includes intermediate vertices but not ends
  ); setq
  (repeat (/ (length vertc) 2); number of VERTex Coordinate lists FOR LWPolyline ONLY [XY coordinates only]
    (setq
      vertpt (list (car vertc) (cadr vertc)); first [remaining] point
      vertpts (cons vertpt vertpts); list of those points
      vertc (cddr vertc); remove first point's coordinates for next one
    ); end setq
  ); end repeat
  (while (not done)
    (setq intpt (list (car intc) (cadr intc))); first remaining point [XY only]
    (if (member intpt vertpts); it's an intermediate vertex
      (setq intc (cdddr intc)); then -- remove first point's coordinates [XYZ] for next one
      (setq done T); else -- it's the [possibly virtual] self-intersection; end (while) loop, keep intpt variable
    ); if
  ); while
  (command "_.pedit" plent "_edit" "_move" intpt "" "" "_break" "" "_go" "_exit" "_close" "");;;;; 3-segment ONLY

  (princ)

); defun

Kent Cooper, AIA
Message 10 of 30
Kent1Cooper
in reply to: barry2104


@barry2104 wrote:

.... 

5) being able to fillet non-standard elements (e.g. spline) would be a bonus ....


It may vary by version, but even back in my ol' 2004, Fillet will accept a Spline as long as what it needs to do with it is trim an end off.  It won't extend an end to meet some other object, probably because of the impossibility of deciding where to go with the virtual intersection point, since Splines run on irregular routes.  That would also make it hard for a routine to come up with a place to extend an end to, but one could incorporate Trim to do what regular Fillet does.  Filleting that way won't join the Spline to whatever else, but will leave it as a Spline, so there's no approximating as would be necessary if it's converted to a Polyline.

 

However, there certainly are still "non-standard elements" [in the sense that regular Fillet refuses to have anything to do with them] that you might want to be able to do something with, such as 3D Polylines or Multilines.  A routine could certainly be made to work with those, at least within certain limits.

Kent Cooper, AIA
Message 11 of 30
JamaL9722060
in reply to: Kent1Cooper

Hi Kent

 

I’m looking for a lisp file that fillets (according to specified radius) all the CONNECTED selected lines/polylines (multiple)

 

Better if the lisp provides tolerance between lines/polylines that will be filleted once selected

 

 

Is there such lisp?

 

Thank you

 

Best

 

Jamal

---------------------------
Jamal Numan
Message 12 of 30
Kent1Cooper
in reply to: JamaL9722060


@JamaL9722060 wrote:

.... 

I’m looking for a lisp file that fillets (according to specified radius) all the CONNECTED selected lines/polylines (multiple)

 

Better if the lisp provides tolerance between lines/polylines that will be filleted once selected

....


As a starting point, try the PJ command in PolylineJoin.lsp, here.  If multiple objects are selected, it joins them into as many Polylines as is appropriate.  It has a 0.0 tolerance that you can change.  Then you presumably would apply Fillet with your desired Radius and the Polyline option to the result(s).  [If a single object is selected, it joins everything it can to it, but without the option of a tolerance.]

Kent Cooper, AIA
Message 13 of 30
marko_ribar
in reply to: JamaL9722060

Jamal, I've written mintfillet.lsp that can be found here

Hope this is what you're looking for...

M.R.

 

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 14 of 30
JamaL9722060
in reply to: marko_ribar

Many thanks Kent and marko for the help,

 

Please, have a on the attached screenshot. What I’m looking for is a lisp file that will fillet all selected (by window selection) lines/polylines (multiple lines/polylines) that are apart within a specified distance

 

Then the end user is assumed to enjoy having

 

  1. Window selection

 2The chance to specify the tolerance (only lines that are apart within that distance will be filleted). For example, if the selected lines/polylines are distant but not within the tolerance, they will not be filleted

 

 3The chance to specify the radius of the fillet (attached)

 

I’m not sure if the lisp files that you have already supplied can be developed

 

Best

 

Jamal

---------------------------
Jamal Numan
Message 15 of 30
marko_ribar
in reply to: JamaL9722060

Jamal, the code is finally changed once again... Sorry for inconvenience for my testing of original code didn't passed for modification of existing fillets where arcs were too small for CAD model space viewport... My final code is little slower, but now it's all as it should be - modifications of existing fillets are correctly processed... Like you stated, Jamal, I think my code is designed the way I thought it would suit the best, and yes I think it can't be further more developed...

 

Hope you'll like my final version, and wish to be used as required in many situations where that's adequate...

 

Sincerely, yours M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 16 of 30
JamaL9722060
in reply to: marko_ribar

Many thanks Marko for the effort

 

Where can I find the most updated lisp? It is not attached to this!

---------------------------
Jamal Numan
Message 17 of 30
marko_ribar
in reply to: JamaL9722060

It is at the same place where it was supplied - here...

 

Only the code was changed...

 

M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 18 of 30
Kent1Cooper
in reply to: marko_ribar


@marko_ribar wrote:

It is at the same place where it was supplied - here...

 

Only the code was changed...

....


I looked at that only very briefly, and haven't wrapped my head around how it goes about everything, but one thing I noticed.  I think you can shortcut the p1 and p2 settings considerably, with the (vlax-curve-get...Point ...) functions.  They will give you the start point and end point of either a Line or an Arc, without needing to distinguish between them.  I believe you could replace this portion:

....

(if (eq (cdr (assoc 0 (entget ent))) "LINE")
      (progn ; then
        (setq p1 (cdr (assoc 10 (entget ent))) p2 (cdr (assoc 11 (entget ent))))
        (setq ptlst (cons p1 ptlst) ptlst (cons p2 ptlst))
      )
      (progn ; else -- Arc
        (setq p1 (polar (cdr (assoc 10 (entget ent))) (cdr (assoc 50 (entget ent))) (cdr (assoc 40 (entget ent)))))
        (setq p2 (polar (cdr (assoc 10 (entget ent))) (cdr (assoc 51 (entget ent))) (cdr (assoc 40 (entget ent)))))
        (setq aptlst1 (cons p1 aptlst1) aptlst2 (cons p2 aptlst2))
        (setq arcchk T)
        (entdel ent)
      )
    )

....

 

with something like this:

 

....

(setq

  p1 (vlax-curve-getStartPoint ent); for either Line or Arc

  p2 (vlax-curve-getEndPoint ent)

); setq

(if (= (cdr (assoc 0 (entget ent))) "LINE")

  (setq ptlst (append (list p1 p2) ptlst)); then

  (progn ; else -- Arc

    (setq aptlst1 (cons p1 aptlst1) aptlst2 (cons p2 aptlst2) arcchk T)

    (entdel ent)

  ); progn

); if

Kent Cooper, AIA
Message 19 of 30
BlackBox_
in reply to: Kent1Cooper

1+ for vlax-Curve-* functions ^^^^

 

... Especially given that they work with both eName, and vla-Objects. :thumbsup:



"How we think determines what we do, and what we do determines what we get."

Message 20 of 30
marko_ribar
in reply to: BlackBox_

The code finally changed to include nested functions that are localized, so they won't be added into (atoms-family)... Also changed retrieving Start and End points of both LINE and ARC entities, as firstly I haven't accounted that I'll use (vl-load-com), but as I noted as (vla-start(end)undomark) function requires (vl-load-com), I've decided to include vlax-curve-getStart(End)Point like BlackBox and Kent Cooper suggested from Autodesk forum...

So this is now final version...

Regards, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)

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

Post to forums  

Autodesk Design & Make Report

”Boost