找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 46|回复: 0

[源码] 外围轮廓线(支持块样条曲线椭圆)

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-7-29 11:21:31 | 显示全部楼层 |阅读模式
  1. 编了一个区域覆盖程序,本来用了李麦克的外围轮廓线程序,但是不支持样条曲线和椭圆,挺苦恼。于是就自己操刀编了一个支持的。实际运行简单图形还行复杂的速度慢,也没其它办法。将就用吧。
  2. ;;; 外轮廓线,返回轮廓拟合线点列表,支持样条曲线,椭圆,块。
  3. (defun outline (ss / alst ar b e1 e2 en en1 en2 en3 ent f i ii j lst lst1 lstx lsty maxpoint minpoint name name1 obj pmax pmin pt
  4.                    snap ss2 ss3 ss4 vc vh vs x zw
  5.                )
  6.   (defun ssnext (en / ss)
  7.     (setq ss (ssadd))
  8.     (while (setq en (entnext en))
  9.       (if (not (member (cdr (assoc 0 (entget en))) (list "ATTRIB" "VERTEX" "SEQEND")))
  10.         (setq ss (ssadd en ss))
  11.       )
  12.     )
  13.     ss
  14.   )
  15.   (vl-load-com)
  16.   (setq snap (getvar "osmode"))
  17.   (setvar "osmode" 0)
  18.   (setq lstx '()
  19.         lsty '()
  20.   )
  21.   (setq en1 (entlast))
  22.   (repeat (setq i (sslength ss))       ; 计算ss最大外围框
  23.     (setq name (ssname ss (setq i (1- i))))
  24.     (vla-getboundingbox (vlax-ename->vla-object name) 'minpoint 'maxpoint)
  25.     (setq pmax (vlax-safearray->list maxpoint)
  26.           pmin (vlax-safearray->list minpoint)
  27.           lstx (cons (car pmin) (cons (car pmax) lstx))
  28.           lsty (cons (cadr pmin) (cons (cadr pmax) lsty))
  29.     )
  30.   )
  31.   (setq lstx (vl-sort lstx '<)
  32.         lsty (vl-sort lsty '<)
  33.   )
  34.   (setq b (* 0.1 (max
  35.                    (- (last lstx) (car lstx))
  36.                    (- (last lsty) (car lsty))
  37.                  )
  38.           )
  39.   )
  40.   (setq lst (list (list (- (car lstx) b) (- (car lsty) b)) (list (+ (last lstx) b) (- (car lsty) b)) (list (+ (last lstx) b)
  41.                                                                                                            (+ (last lsty) b)
  42.                                                                                                      ) (list (- (car lstx) b)
  43.                                                                                                              (+ (last lsty) b)
  44.                                                                                                        )
  45.             )
  46.   )
  47.   (entmake (append
  48.              (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length lst)) (cons 70 1))
  49.              (mapcar
  50.                '(lambda (pt)
  51.                   (cons 10 pt)
  52.                 )
  53.                lst
  54.              )
  55.            )
  56.   )                                       ; 生成大一点的外围框
  57.   (setq vc (trans (getvar "viewctr") 1 2) ; 计算当前窗口坐标用于放大窗口
  58.         vh (getvar "viewsize")
  59.         vs (mapcar
  60.              '/
  61.              (list (* (apply
  62.                         '/
  63.                         (getvar "screensize")
  64.                       ) vh
  65.                    ) vh
  66.              )
  67.              '(2 2)
  68.            )
  69.   )
  70.   (setq zw (mapcar
  71.              '(lambda (f)
  72.                 (trans (mapcar
  73.                          f
  74.                          vc
  75.                          vs
  76.                        ) 2 1
  77.                 )
  78.               )
  79.              '(- +)
  80.            )
  81.   )
  82.   (vl-cmdf "ZOOM" "W" (list (- (car lstx) b) (- (car lsty) b)) (list (+ (last lstx) b) (+ (last lsty) b))) ; 放大窗口
  83.   (setq ss (ssadd (entlast) ss))
  84.   (setq pt (list (- (car lstx) (* 0.5 b)) (- (car lsty) (* 0.5 b))))
  85.   (setq en2 (entlast))
  86.   (vl-cmdf "boundary" "A" "O" "R" "B" "N" ss "" "" pt "") ; 生成面域
  87.   (vl-cmdf "ZOOM" "W" (car zw) (cadr zw)) ; 恢复原窗口
  88.   (setq alst '())
  89.   (if (setq ss2 (ssnext en2))
  90.     (progn
  91.       (repeat (setq i (sslength ss2))
  92.         (setq name (ssname ss2 (setq i (1- i))))
  93.         (if (= (cdr (assoc 0 (entget name))) "REGION")
  94.           (setq obj (vlax-ename->vla-object name)
  95.                 ar (vla-get-area obj)
  96.                 alst (cons (list ar name) alst)
  97.           )
  98.         )
  99.       )
  100.       (setq alst (vl-sort alst (function (lambda (e1 e2)
  101.                                            (> (car e1) (car e2))
  102.                                          )
  103.                                )
  104.                  )
  105.       )
  106.       (setq alst (cdr alst))
  107.       (setq ss4 (ssadd))
  108.       (if (car alst)
  109.         (progn
  110.           (setq name (cadr (car alst)))        ; 取第二大面积,第一大为外围框不选用
  111.           (setq en3 (entlast))
  112.           (vl-cmdf "explode" name)     ; 炸开面域
  113.           (if (setq ss3 (ssnext en3))
  114.             (repeat (setq j (sslength ss3))
  115.               (setq name1 (ssname ss3 (setq j (1- j))))
  116.               (setq obj (vlax-ename->vla-object name1))
  117.               (setq ent (entget name1))
  118.               (if (member (cdr (assoc 0 ent)) (list "SPLINE" "CIRCLE" "ARC" "ELLIPSE"))        ; 如果线是样条椭圆圆圆弧生成拟合线
  119.                 (progn
  120.                   (setq lst (list (vlax-curve-getstartpoint obj)))
  121.                   (setq b (* 0.02 (vlax-curve-getdistatparam obj (vlax-curve-getendparam obj))))
  122.                   (setq ii 1)
  123.                   (repeat 49
  124.                     (setq lst (cons (vlax-curve-getpointatdist obj (* ii b)) lst))
  125.                     (setq ii (1+ ii))
  126.                   )
  127.                   (setq lst (cons (vlax-curve-getendpoint obj) lst))
  128.                   (entmake (append
  129.                              (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length lst)))
  130.                              (mapcar
  131.                                '(lambda (pt)
  132.                                   (cons 10 pt)
  133.                                 )
  134.                                lst
  135.                              )
  136.                            )
  137.                   )
  138.                   (setq ss4 (ssadd (entlast) ss4))
  139.                 )
  140.                 (setq ss4 (ssadd name1 ss4))
  141.               )
  142.             )
  143.           )
  144.           (setvar "peditaccept" 1)
  145.           (vl-cmdf "PEDIT" "M" ss4 "" "J" 0.1 "") ; 将外围线连接成一条多段线,并取端点
  146.           (setq lst1 (mapcar
  147.                        'cdr
  148.                        (vl-remove-if-not '(lambda (x)
  149.                                             (= (car x) 10)
  150.                                           ) (entget (entlast))
  151.                        )
  152.                      )
  153.           )
  154.         )
  155.       )
  156.       (vl-cmdf "erase" (ssnext en1) "")        ; 删除过程中产生的所有图元
  157.     )
  158.   )
  159.   (setvar "osmode" snap)
  160.   lst1
  161. )
  162. ;;; 测试1:生成外围轮廓线
  163. (defun c:aa (/ lst pt ss)
  164.   (if (setq ss (ssget '((0 . "*LINE,CIRCLE,ARC,ELLIPSE,INSERT"))))
  165.     (progn
  166.       (setq lst (outline ss))
  167.       (entmake (append
  168.                  (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length lst)) (cons 70 1)
  169.                        (cons 62 1)
  170.                  )
  171.                  (mapcar
  172.                    '(lambda (pt)
  173.                       (cons 10 pt)
  174.                     )
  175.                    lst
  176.                  )
  177.                )
  178.       )
  179.     )
  180.   )
  181.   (princ)
  182. )
  183. ;;; 测试2:区域覆盖
  184. (defun c:bb (/ #err $orr cp h i lenid ll lst n pt pts s1 snap ss ur w wh)
  185.   (defun gxl-makewipeout (pts / cp h lenid ll lst pt ur w wh) ; 点表转区域覆盖
  186.     (setq lenid (strlen (vl-princ-to-string (vlax-get-acad-object))))
  187.     (cond
  188.       ((= lenid 39)                       ; =>39就是32位AutoCAD
  189.         (if (not (member "acwipeout.arx" (arx)))
  190.           (arxload "acwipeout.arx")
  191.         )
  192.       )
  193.       ((eq 47 lenid)                       ; =>47就是47位autocad
  194.         (if (not (member "acismui.arx" (arx)))
  195.           (arxload "acismui.arx")
  196.         )
  197.       )
  198.     )
  199.     (if (not (equal (car pts) (last pts) 1e-6))
  200.       (setq pts (cons (last pts) pts))
  201.     )
  202.     (setq ll (apply
  203.                'mapcar
  204.                (cons 'min pts)
  205.              )
  206.           ur (apply
  207.                'mapcar
  208.                (cons 'max pts)
  209.              )
  210.           wh (mapcar
  211.                '-
  212.                ur
  213.                ll
  214.              )
  215.           w (car wh)
  216.           h (cadr wh)
  217.           cp (mapcar
  218.                '*
  219.                (mapcar
  220.                  '+
  221.                  ll
  222.                  ur
  223.                )
  224.                '(0.5 0.5 0.5)
  225.              )
  226.     )
  227.     (foreach pt pts
  228.       (setq lst (cons (list 14 (/ (car (setq pt (mapcar
  229.                                                   '-
  230.                                                   pt
  231.                                                   cp
  232.                                                 )
  233.                                        )
  234.                                   ) w
  235.                                ) (- (/ (cadr pt) h))
  236.                       ) lst
  237.                 )
  238.       )
  239.     )
  240.     (setq lst (reverse lst))
  241.     (entmakex (append
  242.                 (list '(0 . "WIPEOUT") '(100 . "AcDbEntity") '(100 . "AcDbWipeout") (cons 10 ll) (list 11 w 0.0) (list 12 0.0 h) '
  243.                       (280 . 1) '(71 . 2)
  244.                 )
  245.                 lst
  246.               )
  247.     )
  248.   )
  249.   (defun #err (s / i n s1)               ; 出错处理子函数
  250.     (setvar "osmode" snap)
  251.     ((if command-s
  252.        command-s
  253.        vl-cmdf
  254.      ) ".undo"
  255.      "e"
  256.     )
  257.     (setq *error* $orr)
  258.   )
  259.   (vl-load-com)
  260.   (vl-cmdf ".UNDO" "BE")               ; 设置undo起点
  261.   (setvar "cmdecho" 0)
  262.   (setq snap (getvar "osmode"))
  263.   (setvar "osmode" 0)
  264.   (setq $orr *error*)
  265.   (setq *error* #err)
  266.   (if (setq ss (ssget '((0 . "*LINE,CIRCLE,ARC,ELLIPSE,INSERT"))))
  267.     (progn
  268.       (setq lst (outline ss))
  269.       (gxl-makewipeout lst)
  270.       (setq name (entlast))
  271.       (vl-cmdf "draworder" name "" "B")
  272.       (vl-cmdf "draworder" ss name "" "F")
  273.     )
  274.   )
  275.   (setvar "osmode" snap)
  276.   (setq *error* $orr)
  277.   (vl-cmdf ".UNDO" "E")                       ; 设置undo终点
  278.   (princ)
  279. )
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-27 10:34 , Processed in 0.128733 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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