明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 10730|回复: 49

又无聊了,发一个源代码 xxdf 智能动态框选倒角 v1.3

    [复制链接]
发表于 2011-5-10 23:20 | 显示全部楼层 |阅读模式

又无聊了。不打算完善,有需要完善的朋友请自行修改或找别人修改,只要你保留源码的作者信息即可
友情提示:这个程序内包含好几个灰常有用的常用函数......
比如:xxflt = 对fillet命令的加强,可以支持 polyline与arc,ellipse,spline之间的倒角.自动判断是否可倒角.
;| (xss-e e) = 取得标志实体后的新生成实体选集
;|(x@_int e1 e2)求两实体交点表最精简代码-------
;;求两组曲线的交点表.

  1. ;| xxdf (智能动态框选倒角) ----by lxx.2007.8
  2. 功能: 动态对曲线倒角,支持 line,arc,ellipse,spline,*polyline
  3.       特点: 1.智能选线.可框选多个,自动找最靠近的曲线进行倒角.
  4.             2.动态.框选时随鼠标移动,实时动态显示倒角结果,可以放弃操作,但绝对不会倒错.
  5.               杜绝因错误倒角导致返工.
  6.       倒角半径由"filletrad" 系统变量决定.也可先输入fillet命令,选r,调整半径.
  7. 返回: nil.倒角过程中命令行无不爽的重复提示.
  8. 版本:
  9. v1.3 消除半径过大及无法倒角引起中断退出。
  10. v1.2 支持单选亮显.支持设置倒角半径.支持回退(undo)
  11. v1.1 消除一些bug,支持连续操作(相当于fillet的m选项)
  12. v1.0
  13. |;
  14. ;;;=====================================主函数===========================================;;;
  15. (defun c:xxdf  (/ !TM !CE !ERR !FR *MYERR A B FR EP1 EP2 GR GRA GRB II OUT OUT2 P1 P2 PP)
  16.   (princ "\n xxdf 智能动态框选倒角 v1.3----by lxx.2007.8")
  17.   (setvar "TRIMMODE" 1)
  18.   (setq !ce  (getvar "cmdecho")
  19. !err *error*
  20. !fr  (getvar "filletrad")
  21. !tm  (getvar "TRIMMODE")
  22. )
  23.   (princ (strcat "\n ** " (if (= !tm 0) "不" "" )"剪切;" " 半径="(rtos !fr 2 4)"**"))
  24.   ;; 自定义出错处理.
  25.   (defun *myerr  (msg / !CE !ERR !FR !TM *ERROR* P1 PP)
  26.     (grvecs (list 0
  27.     p1
  28.     (list (car p1) (cadr pp))
  29.     (list (car p1) (cadr pp))
  30.     pp
  31.     pp
  32.     (list (car pp) (cadr p1))
  33.     (list (car pp) (cadr p1))
  34.     p1
  35.     )
  36.      )
  37.     (command ".undo" "e")
  38.     (setvar "cmdecho" !ce)
  39.     (setvar "filletrad" !fr)
  40.     (setq *error* !err)
  41.     (princ)
  42.     )
  43.   (setvar "cmdecho" 0)
  44.   ;;(setq *error* *myerr)
  45.   ;;循环1.
  46.   (while (not out2)
  47.     (setq out nil)
  48.     (initget "U R  ")
  49.     (setq P1 (getpoint
  50.         "\n选择第一个对象或框选第一点/U-回退/R-半径/<退出>:"
  51.         )
  52.    )
  53.     (cond
  54.       ((and (= 'STR (type p1)) (= "U" (strcase p1))) ; U 回退.
  55.        (command ".undo" 1)
  56.        )
  57.       ((and (= 'STR (type p1)) (= "R" (strcase p1))) ; 半径
  58.        (setq fr (getdist "\n 倒角半径/<0>:"))
  59.        (setvar "filletrad" (if fr fr 0.))
  60.        )
  61.       ((not p1) ; 退出.
  62.        (setq out2 T)
  63.        )
  64.       ((and (listp p1) (setq a (nentselp p1))) ;取第二对象.
  65.        (setq ep1 a)
  66.        (redraw (car ep1) 3)
  67.        (if (and (setq b (entsel "\n 选择第二个对象 <放弃>:"))
  68.   (setq ep2 b)
  69.   )
  70.   (progn (command "_.fillet" ep1 ep2)
  71.     (mystopcmd))
  72.   )
  73.        (redraw (car ep1) 4)
  74.        )
  75.       ((listp p1) ; 取框对角点.
  76.        (princ "\n 选择框选第二点/<放弃>:")
  77.        (command ".undo" "be");!!!  位置是关键!
  78.        (while (not out)
  79.   ;; 循环2
  80.   (setq gr  (grread T 15 2)
  81.         gra (car gr)
  82.         )
  83.   (cond; 放弃.(鼠标右键 回车键 空格)
  84.     ((member gr '((11 0) (2 13) (2 32)))
  85.      (command ".Undo" 1)
  86.      (setq out T)
  87.      ); 关键字
  88.     ((= 2 gra)
  89.      (setq grb (strcase (chr (cadr gr))))
  90.      (cond
  91.        ((= "R" grb) ;输入"R"
  92.         )
  93.        )
  94.      )
  95.     ((= 3 gra); 鼠标左键确定.
  96.      (setq out T)
  97.      )
  98.     ((= 5 gra); 动态取点.
  99.      (if (not pp)
  100.        (setq pp (cadr gr))
  101.        )
  102.      (setq p2 (cadr gr))
  103.      (if (not (equal p2 pp 1e-1))
  104.        (progn
  105.   ;;清旧框
  106.   (grvecs (list 0
  107.          p1
  108.          (list (car p1) (cadr pp))
  109.          (list (car p1) (cadr pp))
  110.          pp
  111.          pp
  112.          (list (car pp) (cadr p1))
  113.          (list (car pp) (cadr p1))
  114.          p1
  115.          )
  116.    )
  117.   ;;画新框
  118.   (grvecs (list 1
  119.          p1
  120.          (list (car p1) (cadr p2))
  121.          (list (car p1) (cadr p2))
  122.          p2
  123.          p2
  124.          (list (car p2) (cadr p1))
  125.          (list (car p2) (cadr p1))
  126.          p1
  127.          )
  128.    )
  129.   (setq pp p2)
  130.   (command ".undo" 1)
  131.   (dofil p1 p2)
  132.   )
  133.        )
  134.      )
  135.     )
  136.   )
  137.        ;; 退出循环2,清选框.
  138.        (grvecs (list 0
  139.        p1
  140.        (list (car p1) (cadr pp))
  141.        (list (car p1) (cadr pp))
  142.        pp
  143.        pp
  144.        (list (car pp) (cadr p1))
  145.        (list (car pp) (cadr p1))
  146.        p1
  147.        )
  148.         )
  149.        )
  150.       )
  151.     (command ".undo" "e")
  152.     )
  153.   (setvar "cmdecho" !ce)
  154.   (setq *error* !err)
  155.   (setq p1 nil)
  156.   (princ)
  157.   )
  158. ;;;=====================================<<<=======================================;;;
  159. ;;;==================================核心函数=====================================;;;
  160. ;|
  161. dofil = 倒角核心函数.
  162. 功能: 自动找到离p1,p2最近的曲线(支持选集多于2个,智能搜索),并倒角.
  163. |;
  164. (defun dofil  (p1 p2 / fil ss ssl sss ii1 ii2 a b ep1 ep2 P x )
  165.   (setq fil '((0 . "*POLYLINE,SPLINE,LINE,ARC,ELLIPSE")))
  166.   (if (and p1
  167.     p2
  168.     (listp p1)
  169.     (listp p2)
  170.     (setq p1 (list (car p1) (cadr p1)))
  171.     (setq p2 (list (car p2) (cadr p2)))
  172.     (not (equal p1 p2))
  173.     (setq ss (ssget "c" p1 p2 fil))
  174.     )
  175.     (progn
  176.       (setq ssl (sslength ss))
  177.       (cond
  178. ((>= ssl 2)
  179.   (setq sss (xss2lst ss))
  180.   (setq ep1
  181.   (mapcar '(lambda (x / p)
  182.       (setq p (vlax-curve-getclosestpointto x p1 nil))
  183.       (list (distance p1 p) x p)
  184.       )
  185.    sss
  186.    )
  187.         )
  188.   (setq a(cdr (car (vl-sort ep1 '(lambda (x y) (< (car x) (car y)))))))
  189.   (setq ep2
  190.   (mapcar '(lambda (x / p)
  191.       (setq p (vlax-curve-getclosestpointto x p2 nil))
  192.       (list (distance p2 p) x p)
  193.       )
  194.    sss
  195.    )
  196.         )
  197.   (setq b(cdr (car (vl-sort ep2 '(lambda (x y) (< (car x) (car y)))))))
  198.   (xxflt a b); 对fillet命令的加强,可以支持 polyline与arc,ellipse,spline之间的倒角.
  199.   )
  200. (T nil)
  201. )
  202.       )
  203.     )
  204.   )
  205. ;; 用于中断命令.
  206. (defun mystopcmd  ()
  207.     (if (/= 0 (getvar "cmdactive"))
  208.       (progn
  209. (princ "\r                                                                            ")
  210. (command)
  211. (princ "\r                                                                            ")
  212. )
  213.       (progn
  214. (princ "\r                                                                             ")
  215. )
  216.       )
  217.     )
  218. ;|xxflt = 对fillet命令的加强,可以支持 polyline与arc,ellipse,spline之间的倒角.自动判断是否可倒角.
  219. 参数: a,b 均为 (元 点)表
  220. 返回值: nil. 如可以倒角,调用fillet命令生成倒角实体.否,返回nil.
  221. |;
  222. (defun xxflt  (a b /  AN1 AN2 CEN E1 E1AN1 E1AN2 E1P1 E1P2 E2 E2AN1 E2AN2 E2P1 E2P2 EE EE2 ENT1 ENT2 O1 O2 OO2
  223.         P1 P2 R 2PI)
  224.   (setq 2PI (* 2 PI))
  225.   (if (and a
  226.     b
  227.     (setq e1 (car a)
  228.      ent1 (entget e1)
  229.      p1  (cadr a)
  230.      )
  231.     (setq e2 (car b)
  232.      ent2 (entget e2)
  233.      p2  (cadr b)
  234.      )
  235.     (not (equal (car a) (car b)))
  236.     (not (equal (cadr a) (cadr b)))
  237.     (setq e1p1 (vlax-curve-getstartpoint e1)
  238.    e1p2 (vlax-curve-getendpoint e1)
  239.    e2p1 (vlax-curve-getstartpoint e2)
  240.    e2p2 (vlax-curve-getendpoint e2))
  241.     (not(or (equal (rem(angle e1p1 e1p2)2PI) (rem(angle e2p1 e2p2)2PI) 1E-2)
  242.      (equal (rem(angle e1p1 e1p2)2PI) (rem(angle e2p2 e2p1)2PI) 1E-2))
  243.      ) ; for 平行直线
  244.     )
  245.     (progn
  246.       (setq r (getvar "FILLETRAD"))
  247.       (if (equal 0.0 r) ; 倒角半径为0 ;;;ok!
  248. (progn
  249.    (setvar "TRIMMODE" 1)
  250.    (setq ee (entlast))
  251.    (command ".fillet" "nea" a "nea" b)
  252.    (if (and (not (entnext ee))
  253.      (equal ent1 (entget e1))
  254.      (equal ent2 (entget e2))
  255.      )
  256.      ;;没有改变,说明fillet不起作用
  257.      (progn (mystopcmd) (command ".undo" 1))
  258.      (mystopcmd)
  259.      )
  260.    )
  261. (progn ;半径不为0,先不修剪,如成功,修剪倒角,不成功则无操作并屏蔽出错提示.
  262.    (setq ee (entlast))
  263.    (setvar "TRIMMODE" 0)
  264.    (command ".fillet" "nea" a "nea" b)
  265.    (mystopcmd)
  266.    (if (and (setq ee2 (entnext ee))
  267.      (SETQ ENT2 (entget ee2))
  268.      (= "ARC" (cdr (assoc 0 ent2)))
  269.      (equal r (cdr (assoc 40 ent2)))
  270.      )
  271.      (progn ;成功
  272.        (setq oo2 (vlax-ename->vla-object ee2)
  273.       o1 (vlax-ename->vla-object e1)
  274.       o2 (vlax-ename->vla-object e2)
  275.       )
  276.        (setq an1  (vla-get-startangle oo2)
  277.       an2  (vla-get-endangle oo2)
  278.       cen  (vlax-get oo2 'center)
  279.       )
  280.        (setq e1an1 (angle cen e1p1)
  281.       e1an2 (angle cen e1p2)
  282.       e2an1 (angle cen e2p1)
  283.       e2an2 (angle cen e2p2)
  284.       )
  285.        (if
  286.   (or (not (and a b an1 an2 e1an1 e1an2 e2an1 e2an2))
  287.       (and (angin e1an1 an1 an2)
  288.     (angin e1an2 an1 an2)
  289.     (not (vlax-invoke o1 'intersectwith oo2 0))
  290.     )
  291.       (and (angin e2an1 an1 an2)
  292.     (angin e2an2 an1 an2)
  293.     (not (vlax-invoke o2 'intersectwith oo2 0))
  294.     )
  295.       ) ; 不能剪切倒角. ;(angin a a1 a2)判断a在a1,a2夹角内.
  296.    (progn
  297.      (command ".undo" 1)
  298.      )
  299.    (progn ; 能剪切倒角.
  300.      (command ".undo" 1)
  301.      (setvar "trimmode" 1)
  302.      (command ".fillet" "nea" a "nea" b)
  303.      (mystopcmd)
  304.      )
  305.    )
  306.        )
  307.      (progn ;如不成功.
  308.        (mystopcmd)
  309.        )
  310.      )
  311.    (setvar "trimmode" 1)
  312.    )
  313. )
  314.       )
  315.     )
  316.   )
  317. ;;(vlax-invoke (vlax-ename->vla-object(car(entsel))) 'intersectwith  (vlax-ename->vla-object(car(entsel))) 0)
  318. ;| (angin a1 a2 a3) = 判断a1在a2,a3夹角内.
  319. 测试: (angin 0.3 4.2 0.2)
  320.       (angin 0.66 0.5 0.2)
  321.       (angin 0.66 0.5 3.4)
  322. |;
  323. (defun angin  (a a1 a2)
  324.   (if (< a1 a2)
  325.     (< a1 a a2)
  326.     (or (< a1 a (* 2 PI)) (< 0 a a2))
  327.   )
  328. )
  329. ;| (xss-e e) = 取得标志实体后的新生成实体选集-----------by lxx.2005.9
  330. 参数: e = 实体名
  331. 返回: 选择集或nil.
  332. |;
  333. ;;
  334. (defun xss-e  (e / ss)
  335.   (if (= 'ENAME (type e))
  336.     (progn
  337.       (setq ss (ssadd))
  338.       (while (setq e (entnext e))
  339. (if (not(wcmatch (cdr (assoc 0 (entget e))) "VERTEX,SEQEND,ATTRIB"))
  340.    (ssadd e ss)
  341.    )
  342. )
  343.       ss
  344.       )
  345.     )
  346.   )
  347. ;|([url=mailto:x@_int]x@_int[/url] e1 e2)求两实体交点表最精简代码-------v1.4 ok----------------------------------陌生人.2004.1
  348. 返回: 有交点返回交点表;无交点返回nil. 当(equal e1 e2),为求自身交点.
  349. v1.3完善pline-2004.2 > 因为pline自身交点返回多余顶点. -> 发现pl经过spline化,返回顶点为控制点,有待改进.!
  350. v1.4 测试成功! 对lwpolyline,polyline 成功.
  351. 测试: ([url=mailto:x@_int]x@_int[/url] (car(entsel)) (car(entsel))) -> ok! e1= e2支持求自身交点.
  352.       (foreach n ([url=mailto:x@_int]x@_int[/url] (setq e (car(entsel))) e) (vl-cmdf ".circle" n "800"))
  353. |;
  354. (defun [url=mailto:x@_int]x@_int[/url]  (ent1 ent2 / colst intlst ptlst obj1 obj2 entl1 e0 ent1 entl2 k n)
  355.   (setq colst nil
  356. intlst nil
  357. ptlst nil
  358. )
  359.   (setq obj1  (vlax-ename->vla-object ent1)
  360. obj2  (vlax-ename->vla-object ent2)
  361. entl1 (entget ent1)
  362. ptlst (xl-div (vlax-invoke obj1 'IntersectWith obj2 0) 3)
  363. ) ;vla交点表.
  364.      ;v1.3 完善pline求自身交点,剔除多余顶点. v1.4改用lsp方法求pl顶点.
  365.   (if (and (equal ent1 ent2)
  366.     (wcmatch (setq e0 (cdr (assoc 0 entl1))) "LWPOLYLINE,POLYLINE")
  367.     )
  368.     (progn
  369.       (if (= "LWPOLYLINE" e0)
  370. (setq colst (xl-div (vlax-get obj1 'coordinates) 2)) ;lwpl是2! v1.3
  371. (while (and (setq ent1 (entnext ent1)
  372.      entl2 (entget ent1)
  373.      )
  374.       (/= "SEQEND" (cdr (assoc 0 entl2)))
  375.       )
  376.      ;else求 2d & 拟合pl线控制点. v1.4
  377.    (setq colst (cons (cdr (assoc 10 entl2)) colst))
  378.    )
  379. )
  380.       (setq intlst
  381.       (apply
  382.         'append
  383.         (mapcar
  384.    '(lambda (x)
  385.       (setq k nil)
  386.      ;!!
  387.       (if (foreach n  colst
  388.      (if (and (equal (car n) (car x) 0.1)
  389.        (equal (cadr n) (cadr x) 0.1)
  390.        )
  391.        (setq K T)
  392.        )
  393.      k ;不可少!
  394.      )
  395.         nil
  396.         (list x)
  397.         )
  398.       )
  399.    ptlst
  400.    )
  401.         )
  402.      )
  403.       ) ;end progn
  404.     (setq intlst ptlst) ;else
  405.     )
  406.   intlst
  407.   )
  408. ;|(xl-div lst nom)表分段. -> 返回 分段的表.   --------------------梁雄啸.2004.1
  409. ; lst = 表,nom = 分段的子表元素个数(从1开始计).
  410. 注意: mapcar 对表操作是从后开始!
  411. |;
  412. (defun xl-div  (lst nom / N NLST NOM X)
  413.   (setq nlst nil
  414. n    0
  415. ) ;是0!!!
  416.   (mapcar '(lambda (x)
  417.       (if (= n nom)
  418.         (setq nlst (append nlst (list (list x)))
  419.        n   1
  420.        )
  421.         (setq nlst (if (null nlst)
  422.        (list (list x))
  423.        (subst (append (last nlst) (list x)) (last nlst) nlst)
  424.        )
  425.        n   (1+ n)
  426.        )
  427.         )
  428.       )
  429.    lst
  430.    )
  431.   nlst
  432.   )
  433. ;;;;;;;;;;;;;;;;;;;;;;;;主程序;;;;;;;;;;;;;;;;;;;;;;;;;;
  434. ;;求两组曲线的交点表.
  435. ;;调用方法: (xssints ss1 ss2)
  436. (defun xssints (ss1 ss2 / n m e1 e2 pts FILTER)
  437.   (setq filter '((0 . "line,*polyline,spline,arc,circle,ellipse")))
  438.   (if (and ss1
  439.     (if (null ss2)
  440.       (setq ss2 ss1)
  441.       ss2
  442.       )
  443.     )
  444.     (repeat (setq n (sslength ss1))
  445.       (setq e1 (ssname ss1 (setq n (1- n))))
  446.       (repeat (setq m (sslength ss2))
  447. (setq e2  (ssname ss2 (setq m (1- m)))
  448.        pts (append pts ([url=mailto:x@_int]x@_int[/url] e1 e2))
  449.        )
  450. )
  451.       )
  452.     )
  453.   pts
  454.   )
  455. ;;;=====================================<<<=======================================;;;
  456. ;; 选集转实体列表.
  457. (defun xss2lst (ss / i e elst)
  458.   (setq i -1)
  459.   (while (setq e (ssname ss (setq i (1+ i))))
  460.     (setq elst (cons e elst))
  461.     )
  462.   (reverse elst)
  463.   )
  464. ;;;=====================================<<<=======================================;;;
  465. (princ "\n xxdf 智能动态框选倒角 v1.3----by lxx.2007.8")
  466. (princ)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 3明经币 +2 金钱 +35 收起 理由
crazylsp + 2 神马都是浮云
大智若禹 + 20
yxr_MJTD + 15 狂刀,很强大。

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下

本帖被以下淘专辑推荐:

  • · 工具|主题: 71, 订阅: 4
发表于 2020-4-17 11:05 | 显示全部楼层
支持狂刀大侠的无私奉献,对我们明经币少的初学者一大贡献!!!
发表于 2019-8-18 18:47 | 显示全部楼层

不错的程序,谢谢分享!要学的太多了
发表于 2020-8-24 10:45 | 显示全部楼层
狂刀代码简约而不简单,谢谢
发表于 2011-5-10 23:31 | 显示全部楼层
本帖最后由 xshrimp 于 2011-5-10 23:33 编辑

支持.狂刀开源..
狂刀代码简约而不简单!
发表于 2011-5-11 12:20 | 显示全部楼层
        猛顶楼主的好贴
发表于 2011-5-11 12:23 | 显示全部楼层
狂刀的作品,个个经典啊
发表于 2011-5-11 17:47 | 显示全部楼层
回复 石井鱼 的帖子

楼主说的是呀,狂刀就是历害
发表于 2011-5-11 23:23 | 显示全部楼层
谢谢楼主分享!
发表于 2011-5-12 11:54 | 显示全部楼层
狂刀太强大了赞一个
发表于 2011-5-12 13:06 | 显示全部楼层
向狂刀致敬
发表于 2011-5-12 15:55 | 显示全部楼层
不错的程序,谢谢分享,收藏了!
发表于 2011-5-12 16:51 | 显示全部楼层
强烈支持狂刀前辈
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-19 01:43 , Processed in 0.474744 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表