天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 32|回复: 0

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

[复制链接]
  • TA的每日心情
    开心
    3 天前
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    99

    主题

    11

    回帖

    1234

    积分

    管理员

    积分
    1234
    QQ
    发表于 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. )
    复制代码

     

     

     

     

    [源码] 外围轮廓线(支持块样条曲线椭圆)
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-10-27 08:31 , Processed in 0.162902 second(s), 25 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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