Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Reply
Message 1 of 7
NirantarVidyarthee
617 Views, 6 Replies

Fillet API

It is recommended that you should avoid using (command) functions in AutoLISP.

 

But it seems that trim and fillet / chamfer are three tasks for which using the (command) function is the only viable alternative. (even com methods are not available for them).

 

I would like to here what you all think about it.

6 REPLIES 6
Message 2 of 7
devitg
in reply to: NirantarVidyarthee

You can recreate , by lisp, both or any other COMMAND .

 

And as last chance , use VL-CMDF , it will evaluate  if all is correct before the task is do.

 

 

Message 3 of 7


@NirantarVidyarthee wrote:

It is recommended that you should avoid using (command) functions in AutoLISP.

 

But it seems that trim and fillet / chamfer are three tasks for which using the (command) function is the only viable alternative. (even com methods are not available for them).

 

I would like to here what you all think about it.


I've never agreed with that "should avoid" philosophy.  Yes, there are circumstances in which you can't use (command) [e.g. in a reactor], and others in which you can save a detectable amount of time using other methods [e.g. drawing comparatively large numbers of things], so you should be aware of situations where it's worth considering which approach to use.  But most of the time, (command) works fine, and it very often lets you do something with a lot less code.  I think of the (command) [or (vl-cmdf) if you prefer] function as essentially a sub-routine -- in many cases it will figure out a heck of a lot of stuff for you, so you don't have to, and I'm glad to take advantage of that.  Another way to think of it:  the (command) function is included in AutoLISP for a reason [i.e. if it were something one should avoid, maybe it wouldn't be there].

 

Yes, as devitg says, you can probably duplicate what Fillet and Trim and Extend do with things like (subst)/(entmod) and (entmake) and some (vla...) functions.  And in the case of, for example, Filleting two Lines with a zero radius, that's not too complicated [though you do need to figure out not only their intersection point, but also which end of each Line to change, based on the intersection or apparent intersection and its relationship to both the pick points and the direction in which the Lines were drawn].  But imagine the calculating shenanigans you would have to go through to do something as dead-simple for (command) to do as a non-zero-radius Fillet on two Arcs -- finding the location of the center of the new Arc, and its starting and ending angles, and figuring out which end of each of the existing Arcs to change, and their new starting or ending angles, affected by whether the two existing Arcs curve in the same or opposite directions, etc., etc.

 

But plenty of other commands besides those, that could be replicated using (entmake) etc., can also be hugely easier using (command).  Consider, for example, a polar Array of a possibly multi-object User selection that might include various different kinds of entities.  It would be complicated enough to work out how to calculate all the instances of just one type of object around the array, and then you'd need to come up with a completely different set of calculations for every different entity type that a User might select in using the routine.

 

For an extreme example of something that (command) does more easily, look at this thread.  If you choose to try it out, get the version of InsulBattPoly.lsp from Message 11 [or from here], but whether you do or not, look at the image attached to Message 2.  In the lower right corner is a fun possibility that you'd never actually do, labeled (IB Squared!).  It's the result of using the IB routine to make a Polyline representation of a short stretch of Insulation Batting based on an initial straight Line, and then using it again on the result of that, making a Polyline that represents insulation running along a route that's the shape of insulation squiggling.  As I recall, that Polyline has something over 1,700 vertices, with multiple arc segments mixed with line segments in each loop, and very subtly varying bulge factors on arc segments as the path swings around through varying degrees of curvature.  It's complicated enough to get the IB routine to do that using (command), as you'll see if you open up the .lsp file, but I defy anyone to accomplish something like that using (entmake).

 

There are also certain System Variables that are read-only [e.g.UCSORG], so that you can't change them using (setvar), but the way you do so is with the appropriate command.

Kent Cooper, AIA
Message 4 of 7
pbejse
in reply to: NirantarVidyarthee


@NirantarVidyarthee wrote:

It is recommended that you should avoid using (command) functions in AutoLISP.

 

But it seems that trim and fillet / chamfer are three tasks for which using the (command) function is the only viable alternative. (even com methods are not available for them).

 

I would like to here what you all think about it.


Its not that you have to "avoid" a call to command, some task is loads easier and better using native commands as long as you provide the necessary error checking. perhaps vl-cmdf would be more appropriate as devitg and kent suggested.

 

There are instances that using command wont cut it, like processing objects thru multiple layouts as the layout needs to be active on runtime where the objects is located when using command fucntions. sure you can use (setvar 'ctab layoutname) but would you really want to do that with like 20 layout tabs?

 

Anyhoo, What do you have in mind?

Message 5 of 7
sanganaksakha
in reply to: pbejse

I have faced problems with programs that use (command) function when migrating to higher versions because of changes to syntax etc. Hence, I prefer not to use (command) function.

 

But in case of fillet / chamfer, I thought that it would not be worth the efforts to write an alternative function. I just wanted confitmation for this.

 

Thanks to all.

 

Message 6 of 7
pbejse
in reply to: sanganaksakha


@sanganaksakha wrote:

I have faced problems with programs that use (command) function when migrating to higher versions because of changes to syntax etc. Hence, I prefer not to use (command) function.

 

But in case of fillet / chamfer, I thought that it would not be worth the efforts to write an alternative function. I just wanted confitmation for this.

 

Thanks to all.

 


True in most cases, however, you can  use initcommandversion to force  version compatibility.

 

 

 

 

Message 7 of 7

Here for fun, a code without (command) for make a fillet.

Can be an alternative to command fillet, i don't known...

 

It's a try !

 

(defun z_dir (p1 p2 / )
  (trans
    '(0.0 1.0 0.0)
    (mapcar
      '(lambda (k)
        (/ k
          (sqrt
            (apply '+
              (mapcar
                '(lambda (x) (* x x))
                (mapcar '- p2 p1)
              )
            )
          )
        )
      )
      (mapcar '- p2 p1)
    )
    0
  )
)
(defun ang_x (px p1 p2 / l_pt l_d p ang)
  (setq
    l_pt (mapcar '(lambda (x) (list (car x) (cadr x) (caddr x))) (list px p1 p2))
    l_d (mapcar 'distance l_pt (append (cdr l_pt) (list (car l_pt))))
    p (/ (apply '+ l_d) 2.0)
    ang (* (atan (sqrt (/ (* (- p (car l_d)) (- p (caddr l_d))) (* p (- p (cadr l_d)))))) 2.0)
  )
)
(defun det_wh (px p1 p2 / v1 v2 det_or)
  (setq
    v1 (mapcar '- p2 p1)
    v2 (mapcar '- px p1)
  )
  (if (> (apply '(lambda (x1 y1 z1 x2 y2 z2) (- (* x1 y2) (* y1 x2))) (append v1 v2)) 0.0) 1 -1)
)
(defun k_th (p1 p2 c / k)
  (setq k (/ c (distance p1 p2)))
  (mapcar '+ (mapcar '* (mapcar '- p2 p1) (list k k k)) p1)
)
(defun c:my_filletrad ( / js1 js2 ps1 ps2 pt_lst pt l3 alpha chord p_o a1 a2) ; key_fillet
  (princ "\nSelect first line: ")
  (while (or (null (setq js1 (entsel))) (/= (cdr (assoc 0 (entget (car js1)))) "LINE")))
  (princ "\nSelect second line: ")
  (while (or (null (setq js2 (entsel))) (/= (cdr (assoc 0 (entget (car js2)))) "LINE")))
  (setq
    ps1 (trans (cadr js1) 1 0)
    ps2 (trans (cadr js2) 1 0)
    js1 (entget (car js1))
    js2 (entget (car js2))
    pt_lst (list (cdr (assoc 10 js1)) (cdr (assoc 11 js1)) (cdr (assoc 10 js2)) (cdr (assoc 11 js2)))
    pt (inters (car pt_lst) (cadr pt_lst) (caddr pt_lst) (cadddr pt_lst) nil)
  )
  (cond
    (pt
      (if (eq (det_wh (cadddr pt_lst) (car pt_lst) (cadr pt_lst)) (det_wh (caddr pt_lst) (car pt_lst) (cadr pt_lst)))
        (if (> (distance pt (caddr pt_lst)) (distance pt (cadddr pt_lst)))
          (setq l3 (list pt (caddr pt_lst)))
          (setq l3 (list pt (cadddr pt_lst)))
        )
        (if (eq (det_wh ps2 (car pt_lst) (cadr pt_lst)) (det_wh (caddr pt_lst) (car pt_lst) (cadr pt_lst)))
          (setq l3 (list pt (caddr pt_lst)))
          (setq l3 (list pt (cadddr pt_lst)))
        )
      )
      (if (eq (det_wh (cadr pt_lst) (caddr pt_lst) (cadddr pt_lst)) (det_wh (car pt_lst) (caddr pt_lst) (cadddr pt_lst)))
        (if (> (distance pt (car pt_lst)) (distance pt (cadr pt_lst)))
          (setq l3 (cons (car pt_lst) l3))
          (setq l3 (cons (cadr pt_lst) l3))
        )
        (if (eq (det_wh ps1 (caddr pt_lst) (cadddr pt_lst)) (det_wh (car pt_lst) (caddr pt_lst) (cadddr pt_lst)))
          (setq l3 (cons (car pt_lst) l3))
          (setq l3 (cons (cadr pt_lst) l3))
        )
      )
; Classic prompt
;|      (initget 4)
      (setq key_fillet
        (getdist
          (strcat
            "\nSpecify fillet radius <"
            (rtos (getvar "FILLETRAD"))
            ">:"
          )
        )
      )
      (if (null key_fillet) (setq key_fillet (getvar "FILLETRAD")) (setvar "FILLETRAD" key_fillet))|;
; Or auto radius fillet
      (setvar "FILLETRAD"
        (distance
          (inters
            ps1
            (polar ps1 (+ (angle (car l3) (cadr l3)) (* pi 0.5)) (distance (cadr l3) ps1))
            (polar (cadr l3) (angle (cadr l3) (caddr l3)) (distance (cadr l3) ps1))
            (polar
              (polar (cadr l3) (angle (cadr l3) (caddr l3)) (distance (cadr l3) ps1))
              (+ (angle (cadr l3) (caddr l3)) (* pi 0.5))
              (distance (cadr l3) ps1)
            )
            nil
          )
          ps1
        )
      )
      (setq
        alpha (ang_x (cadr l3) (car l3) (caddr l3))
        l_tg (* (getvar "FILLETRAD") (/ 1.0 (/ (sin (* alpha 0.5)) (cos (* alpha 0.5)))))
        js1 (subst (cons 10 (car l3)) (assoc 10 js1) js1)
        js2 (subst (cons 10 (caddr l3)) (assoc 10 js2) js2)
      )
      (entmod ; put entmod in rem dor not trim it
        (setq js1 (subst (cons 11 (k_th pt (car l3) l_tg)) (assoc 11 js1) js1))
      )
      (entmod ; put entmod in rem dor not trim it
        (setq js2 (subst (cons 11 (k_th pt (caddr l3) l_tg))  (assoc 11 js2) js2))
      )
      (setq
        p_o (k_th pt (mapcar '* (mapcar '+ (cdr (assoc 11 js1)) (cdr (assoc 11 js2))) '(0.5 0.5 0.5)) (+ (getvar "FILLETRAD") (* (getvar "FILLETRAD") (1- (/ 1.0 (sin (* alpha 0.5)))))))
        a1 (angle p_o (cdr (assoc 11 js1)))
        a2 (angle p_o (cdr (assoc 11 js2)))
        dxf_210 (z_dir p_o (cdr (assoc 11 js1)))
      )
      (entmake
        (list
          (cons 0 "ARC")
          (cons 100 "AcDbEntity")
          (assoc 67 js1)
          (assoc 410 js1)
          (cons 8 (getvar "CLAYER"))
          (if (assoc 62 js1) (assoc 62 js1) (cons 62 256))
          (if (assoc 6 js1) (assoc 6 js1) (cons 6 "BYLAYER"))
          (cons 38 (+ (cadddr (assoc 10 js1)) (getvar "ELEVATION")))
          (cons 39 (getvar "THICKNESS"))
          (cons 100 "AcDbCircle")
          (cons 10 (trans p_o 0 dxf_210))
          (cons 40 (getvar "FILLETRAD"))
          (cons 210 dxf_210) 
          (cons 100 "AcDbArc")
          (cons 50
            (if (equal (* (+ (max a1 a2) (min a1 a2)) 0.5) (angle p_o pt) 1E-8)
              (min a1 a2)
              (max a1 a2)
            )
          )
          (cons 51
            (if (equal (* (+ (max a1 a2) (min a1 a2)) 0.5) (angle p_o pt) 1E-8)
              (max a1 a2)
              (min a1 a2)
            )
          )
        )
      )
    )
    (T
      (princ "\nCan't fillet lines in differents planes!")
    )
  )
  (prin1)
)

 

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

Post to forums  

Autodesk Design & Make Report

”Boost