找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 10871|回复: 22

[研讨] 关于如何计算XClip剪裁边界顶点坐标的研究

[复制链接]
发表于 2013-5-22 21:28:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
我们知道,对于图块的边界剪裁,可以使用XClip命令,使得剪裁边界之外的部分不可见!我们可以使用命令XClip-> P 选项,生成多段线,通过计算生成的多段线得到剪裁边界的坐标!
其实这个剪裁边界的坐标是储存在ACAD_XDICTIONARY词典里的,通过如下代码可获得剪裁边界数据:
  1. (defun GetSpatialFilter (ename / Data Dict tempDict)
  2.     ; Get the xclip boundry
  3.    
  4.     (if
  5.         (and
  6.             (setq Data (entget ename))
  7.             (setq Dict (cdr (assoc 360 Data)))
  8.             (setq tempDict (dictsearch Dict "ACAD_FILTER"))
  9.             (setq tempDict (dictsearch (cdr (assoc -1 tempDict)) "SPATIAL"))
  10.         )
  11.         (cons '(0 . "SPATIAL_FILTER") (member (assoc 100 tempDict) tempDict))
  12.     )
  13. )
  14. ;;测试
  15. (GetSpatialFilter (car(entsel "\n选择剪裁块:")))
  16. ;;返回
  17. ((0 . "SPATIAL_FILTER") (100 . "AcDbFilter") (100 . "AcDbSpatialFilter")
  18. (70 . 4) (10 44.1073 36.0989 0.0) (10 44.1073 77.113 0.0) (10 91.0409 77.113
  19. 0.0) (10 91.0409 36.0989 0.0) (210 0.0 0.0 1.0) (11 0.0 0.0 0.0) (71 . 1) (72 .
  20. 0) (73 . 0) (40 . 1.0) (40 . 0.0) (40 . 0.0) (40 . -62.7683) (40 . 0.0) (40 .
  21. 1.0) (40 . 0.0) (40 . -54.9313) (40 . 0.0) (40 . 0.0) (40 . 1.0) (40 . 0.0) (40
  22. . 1.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 1.0) (40 . 0.0) (40 .
  23. 0.0) (40 . 0.0) (40 . 0.0) (40 . 1.0) (40 . 0.0))


组码10即为顶点坐标,70为顶点数,后面的组码40好像是应为坐标转换矩阵,具体怎么组成矩阵不太明白!
在网上找了个LeeMac的计算剪裁对象边界顶点坐标的程序如下:
  1. ;; http://www.theswamp.org/index.php?topic=39201.0 LeeMac
  2. (defun _XClipBoundary ( ename / __XClipBoundary elist xlist _xang _xnor mxv mxm trp)
  3. ;; Matrix x Vector - Vladimir Nesterovsky
  4. ;; Args: m - nxn matrix, v - vector in R^n

  5. (defun mxv ( m v )
  6.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  7. )

  8. ;; Matrix x Matrix - Vladimir Nesterovsky
  9. ;; Args: m,n - nxn matrices

  10. (defun mxm ( m n )
  11.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
  12. )

  13. ;; Matrix Transpose - Doug Wilson
  14. ;; Args: m - nxn matrix

  15. (defun trp ( m ) (apply 'mapcar (cons 'list m)))

  16.     (defun __XClipBoundary ( ename / xdict )
  17.         (if
  18.             (setq xdict (cdr (assoc 360 (entget ename))))
  19.             (__XClipBoundary xdict)
  20.             (if
  21.                 (and
  22.                     (eq "SPATIAL_FILTER" (cdr (assoc 0 (setq ename (entget ename)))))
  23.                     (eq 1 (cdr (assoc 71 ename)))
  24.                 )
  25.                 (
  26.                     (lambda ( massoc ) (massoc 10 ename))
  27.                     (lambda ( key elist / item )
  28.                         (if (setq item (assoc key elist))
  29.                             (cons (cdr item) (massoc key (cdr (member item elist))))
  30.                         )
  31.                     )
  32.                 )
  33.             )
  34.         )
  35.     )

  36.     (defun __dxf ( key lst ) (cdr (assoc key lst)))

  37.     (setq elist (entget ename)
  38.           _xang (__dxf  50 elist)
  39.           _xnor (__dxf 210 elist)
  40.     )
  41.     (if (setq xlist (__XClipBoundary ename))
  42.         (
  43.             (lambda ( matrix )
  44.                 (
  45.                     (lambda ( vector )
  46.                         (mapcar
  47.                             (function
  48.                                 (lambda ( point )
  49.                                     (mapcar '+ (mxv matrix point) vector)
  50.                                 )
  51.                             )
  52.                             xlist
  53.                         )
  54.                     )
  55.                     (mapcar '- (trans (__dxf 10 elist) _xnor 0)
  56.                         (mxv matrix
  57.                              (__dxf 10 (tblsearch "BLOCK" (__dxf 2 elist)))
  58.                         )
  59.                     )
  60.                 )
  61.             )
  62.             (mxm
  63.                 (mapcar
  64.                     (function
  65.                         (lambda ( v ) (trans v 0 _xnor t))
  66.                     )
  67.                    '(
  68.                         (1.0 0.0 0.0)
  69.                         (0.0 1.0 0.0)
  70.                         (0.0 0.0 1.0)
  71.                     )
  72.                 )
  73.                 (mxm
  74.                     (list
  75.                         (list (cos _xang) (sin (- _xang)) 0.0)
  76.                         (list (sin _xang) (cos _xang)     0.0)
  77.                         (list 0.0         0.0             1.0)
  78.                     )
  79.                     (list
  80.                         (list (__dxf 41 elist) 0.0 0.0)
  81.                         (list 0.0 (__dxf 42 elist) 0.0)
  82.                         (list 0.0 0.0 (__dxf 43 elist))
  83.                     )
  84.                 )
  85.             )            
  86.         )
  87.     )
  88. )

这个程序计算的剪裁边界的顶点坐标好像也不对!
请大家来研讨一下,如何求得如下图的剪裁边界顶点坐标?
xclip.jpg
上图2、3、4是由1复制而来,然后进行旋转或缩放,由函数GetSpatialFilter 得到的顶点坐标数据完全一样!怎样才能求出这些剪裁块的顶点坐标呢?
请点击此处下载

查看状态:需购买或无权限

您的用户组是:游客

文件名称:xclip.rar 
下载次数:48  文件大小:25.97 KB 
下载权限: 不限 以上  [免费赚D豆]

DWG测试图

请各位高人来指点指点!O(∩_∩)O谢谢!

评分

参与人数 4D豆 +23 贡献 +1 收起 理由
xshrimp + 5 出题引导交流奖!
XDSoft + 10 + 1 好主题奖!
ScmTools + 3 出题引导交流奖!
牢固 + 5 好主题奖!

查看全部评分

本帖被以下淘专辑推荐:

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-24 10:59:37 | 显示全部楼层
本帖最后由 牢固 于 2013-5-24 12:34 编辑

搞清楚了XCLIP剪裁边界的内在机制,下面要重新修改剪裁块的边界就很容易了。我们来看,11楼的代码由剪裁块计算出顶点的坐标是这样一个过程:
1、通过SPATIAL_FILTER对象,得到剪裁边界的原始定义顶点坐标表PL和该坐标转换到图块定义的转换矩阵M
2、通过图块计算出图块的BlockDef->BlockRef的转换矩阵M1
3、PL经过M和M1两次矩阵转换,就得到了剪裁边界的WCS坐标
重构剪裁边界,就是上述过程的一个逆过程:

1、根据图块计算出图块的BlockRef->BlockDef矩阵,即图块的逆矩阵M0
2、将新边界的顶点WCS坐标PL根据Mo矩阵转换到图块的定义坐标系
3、通过SPATIAL_FILTER对象,得到剪裁边界的原始定义顶点转换到图块定义的转换矩阵M1,并计算出M2的逆矩阵
4、再将第二步转换后的PL经过M2矩阵转换,转换到剪裁边界的原始定义坐标系
5、用新的PL坐标表更新SPATIAL_FILTER对象的的10组码表,并根据PL顶点个数更新70组码
6、更新显示图块

                               
登录/注册后可看大图

相关矩阵函数参见高飞鸟的帖子:Lisp论矩阵
  1. ;;修改XCLIP边界
  2. (defun c:tt ()
  3.   (while
  4.     (and
  5.       (setq e (car(entsel "\n选择剪裁块:")))
  6.       (setq Poly (car(entsel "\n选择剪裁边界:")))
  7.       )
  8.     (gxl-EditXclipBoundary e poly)
  9.     )
  10.   (princ)
  11.   )

  12. ;;(gxl-EditXclipBoundary ENAME BOUNDARY) 重构XCLip的剪裁边界,参数 ENAME=剪裁块图元 BOUNDARY=点表或多段线图元
  13. ;;(gxl-EditXclipBoundary (car(entsel "\n选择剪裁块:")) (car(entsel "\n选择剪裁边界:")))
  14. (defun gxl-EditXclipBoundary (ENAME BOUNDARY        /       ISXCLIP
  15.                                     PTLIST  PLIST   EL      M0
  16.                                     DXF40   M1      M       N
  17.                                     )
  18.   (defun IsXClip (ename / xdict)
  19.     (if
  20.       (setq xdict (cdr (assoc 360 (entget ename))))
  21.        (IsXClip xdict)
  22.        (if
  23.          (eq "SPATIAL_FILTER"
  24.                (cdr (assoc 0 (setq ename (entget ename))))
  25.                )
  26.           ename
  27.           )
  28.        )
  29.     )
  30.   (if (= 'ename (type Boundary))
  31.     (setq PList (gxl-get_poly_ptList3 Boundary 0.05))
  32.     (if (= 'list (type Boundary))
  33.       (setq pList Boundary)
  34.       )
  35.     )
  36.   (if (and (setq el (IsXCLIP ename))
  37.            PList
  38.            )
  39.     (progn
  40.       ;;计算图块的逆转换矩阵 Ref-> Del
  41.       (setq m0 (apply 'MAT:DISPTOMATRIX (MAT:RevRefGeom ename)))
  42.       ;;计算剪切边界顶点转换到图块定义的矩阵
  43.       (setq dxf40 (vl-remove-if-not '(lambda (x) (= (car x) 40)) el) ) ;_ 矩阵数据表     (if (= 1 (cdr (assoc 72 el))) (setq dxf40 (cdr dxf40)))
  44.       (setq m1
  45.              (list
  46.                (mapcar 'cdr
  47.                        (list (nth 0 dxf40)
  48.                              (nth 1 dxf40)
  49.                              (nth 2 dxf40)
  50.                              (nth 3 dxf40)
  51.                              )
  52.                        )
  53.                (mapcar 'cdr
  54.                        (list (nth 4 dxf40)
  55.                              (nth 5 dxf40)
  56.                              (nth 6 dxf40)
  57.                              (nth 7 dxf40)
  58.                              )
  59.                        )
  60.                (mapcar 'cdr
  61.                        (list (nth 8 dxf40)
  62.                              (nth 9 dxf40)
  63.                              (nth 10 dxf40)
  64.                              (nth 11 dxf40)
  65.                              )
  66.                        )
  67.                '(0 0 0 1)
  68.                )
  69.             )
  70.       ;;矩阵m1求逆,计算出图块定义坐标变换到剪切边界的定义坐标系
  71.       (setq m1 (Mat:Inverse m1))
  72.       ;;计算坐标PList经过m0 m1 矩阵变换到剪切边界的定义坐标系的矩阵
  73.       (setq m (MAT:MXM m1 m0))
  74.       ;;计算PList经过矩阵m变换后的坐标
  75.       (setq PList (mapcar '(lambda (x) (MAT:MXP m x)) Plist))
  76.       (setq n (length PList)) ;_ 剪切边界的顶点数
  77.       (setq el (subst (cons 70 n) (assoc 70 el) el))
  78.       (setq el
  79.              (append
  80.                (reverse (member (assoc 70 el) (reverse el)))
  81.                (mapcar '(lambda (x) (cons 10 x)) PList)
  82.                (member (assoc 210 el) el)
  83.                )
  84.             )
  85.       ;;更新边界
  86.       (entmod el)
  87.       (entupd ename) ;_ 更新图块
  88.       )
  89.     )
  90.   )
  91. ;;;gxl-get_poly_ptList3 返回多义线顶点点列表,有圆弧则用一定角度分割圆弧,闭合多义线点表不含闭合点坐标
  92. (defun gxl-get_poly_ptList3 (ENT FGX  /      OBJNAME       VERTEXSNUM
  93.          N  PT     PLIST  SECDEV BUGLE
  94.          BJ  D1     D2     D       K
  95.          D0  PARAM
  96.         )
  97.   (setq objname
  98.    (cond
  99.      ((GXL-CATCHAPPLY vla-get-ObjectName (list ent)))
  100.      ((GXL-CATCHAPPLY gxl-dxf (list ent 0)))
  101.      )
  102.   )
  103.   (setq  vertexsNum
  104.    (fix (vlax-curve-getEndParam ent))
  105.   n 0
  106.   ) ;_ 结束setq
  107.   (cond  ((or
  108.      (= "AcDbCircle" objname)
  109.      (= "CIRCLE" objname)
  110.      )
  111.    (if (equal fgx 0 1e-6)
  112.      (setq fgx pi2)
  113.    )
  114.    (setq vertexsNum
  115.     (fix (/ 2pi fgx))
  116.          n 0
  117.    )
  118.    (repeat vertexsNum
  119.      (setq pt (vlax-curve-getPointAtParam ent (* n fgx)))
  120.      (setq plist (cons pt plist)
  121.      n     (1+ n)
  122.      )
  123.    )
  124.    (reverse plist)

  125.   )
  126.   (t
  127.    (if (or
  128.          (= "AcDb2dPolyline" objName)
  129.          (= "POLYLINE" objName)
  130.          )
  131.      (progn
  132.        (repeat vertexsNum
  133.          (setq pt (vlax-curve-getPointAtParam ent n))
  134.          (setq plist (cons pt plist))
  135.          (setq pt (vlax-curve-getPointAtParam ent (+ 0.25 n)))
  136.          (setq plist (cons pt plist))
  137.          (setq pt (vlax-curve-getPointAtParam ent (+ 0.5 n)))
  138.          (setq plist (cons pt plist))
  139.          (setq pt (vlax-curve-getPointAtParam ent (+ 0.75 n)))
  140.          (setq plist (cons pt plist))
  141.          (setq n (1+ n))
  142.        )
  143.        (if (not (vlax-curve-isClosed ent))
  144.          (setq plist (cons (vlax-curve-getEndPoint ent) plist))
  145.        ) ;_ 结束if
  146.        (reverse plist)

  147.      )
  148.            
  149.      (if (equal fgx 0 1e-6)
  150.              (progn
  151.                (if (= 'ename (type ent)) (setq ent (vlax-ename->vla-object ent)))
  152.                (setq h (list(cdr (assoc 38 (setq ent (entget ent))))))
  153.        (mapcar '(lambda (a) (cdr (append a h))) (vl-remove-if-not '(lambda (x) (= 10 (car x))) ent))
  154.                )
  155.        (progn
  156.          
  157.          (repeat vertexsNum
  158.      (if (setq secdev (vlax-curve-getSecondDeriv ent n))
  159.        (progn
  160.      (setq pt    (vlax-curve-getPointAtParam ent n)
  161.            bugle (vla-GetBulge ent n)
  162.      ) ;_ 结束setq
  163.      (setq plist (cons pt plist))
  164.      (if (/= bugle 0.0)
  165.        (progn
  166.          (setq bj (* (atan (abs bugle)) 4))
  167.          (setq d1   (vlax-curve-getdistAtParam ent n)
  168.          d2   (vlax-curve-getdistAtParam ent (1+ n))
  169.          d   (- d2 d1)
  170.          k   (fix (/ bj fgx))
  171.          d0   (/ 1.0 (1+ k))
  172.          param n
  173.          ) ;_ 结束setq
  174.          (if (equal d0 1.0 0.001)
  175.            (setq plist (cons (vlax-curve-getPointAtParam
  176.              ent
  177.              (+ 0.5 param)
  178.            )
  179.            plist
  180.            )
  181.            )
  182.            (repeat k
  183.        (setq plist (cons (vlax-curve-getPointAtParam
  184.                ent
  185.                (setq param (+ param d0))
  186.              )
  187.              plist
  188.              )
  189.        )
  190.            )
  191.          )
  192.        ) ;_ 结束progn
  193.      ) ;_ 结束if
  194.      )
  195.        )
  196.      (setq n (1+ n))
  197.          ) ;_ 结束repeat
  198.          (if (not (vlax-curve-isClosed ent))
  199.      (setq plist (cons (vlax-curve-getEndPoint ent) plist))
  200.          ) ;_ 结束if
  201.          (reverse plist)
  202.        )
  203.      )
  204.    )
  205.   )
  206.   )
  207. )

  208. (defun gxl-CatchApply ( fun args / result )
  209.   (if
  210.     (not
  211.       (vl-catch-all-error-p
  212.         (setq result
  213.           (vl-catch-all-apply (if (= 'SYM (type fun)) fun (function fun)) args)
  214.         )
  215.       )
  216.     )
  217.     result
  218.   )
  219. )

  220. ;;; Mat:Inverse 求逆矩阵
  221. ;(Mat:Inverse m)
  222. ;;--------------------=={ Inverse Matrix }==------------------;;
  223. ;;                                                            ;;
  224. ;;  Implements the Gauss-Jordan Elimination algorithm to      ;;
  225. ;;  inverse a non-singular nxn matrix.                        ;;
  226. ;;------------------------------------------------------------;;
  227. ;;  Author: Lee Mac, Copyright ? 2011 - www.lee-mac.com       ;;
  228. ;;------------------------------------------------------------;;
  229. ;;  Arguments: m - nxn Matrix                                 ;;
  230. ;;------------------------------------------------------------;;
  231. ;;  Returns:  Matrix inverse, or nil if matrix is singular    ;;
  232. ;;------------------------------------------------------------;;
  233. ;; http://www.theswamp.org/index.php?topic=22638.msg439381#msg439381
  234. (defun Mat:Inverse ( m / _identity _eliminate p r x )
  235.   ;;计算单位矩阵
  236.   (defun _identity ( n / i j l m ) (setq i 1)
  237.     (repeat n (setq j 0)
  238.       (repeat n
  239.         (setq l (cons (if (= i (setq j (1+ j))) 1. 0.) l))
  240.       )
  241.       (setq m (cons l m) l nil i (1+ i)) m
  242.     )
  243.   )

  244.   (defun _eliminate ( m p )
  245.     (mapcar
  246.       (function
  247.         (lambda ( x / d )
  248.           (setq d (car x)) (mapcar (function (lambda ( a b ) (- a (* d b)))) (cdr x) p)
  249.         )
  250.       )
  251.       m
  252.     )
  253.   )
  254.   (setq m (mapcar 'append m (_identity (length m))))
  255.   
  256.   (while m
  257.     (setq p (apply 'max (mapcar 'abs (mapcar 'car m))))
  258.     (while (not (equal p (abs (caar m)) 1e-14))
  259.       (setq m (append (cdr m) (list (car m))))
  260.     )
  261.     (if (equal 0.0 (caar m) 1e-14)
  262.       (setq m nil)
  263.       (setq p (/ 1. (caar m))
  264.             p (mapcar (function (lambda ( x ) (* p x))) (cdar m))
  265.             m (_eliminate (cdr m) p)
  266.             r (cons p (_eliminate r p))
  267.       )
  268.     )
  269.   )
  270.   (reverse r)
  271. )



点评

支持一下  发表于 2015-1-20 14:46

评分

参与人数 3D豆 +20 贡献 +2 收起 理由
Highflybird + 5 + 1 技术引导讨论和指点奖!
XDSoft + 10 + 1 有始有终奖!
Lispboy + 5 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-23 23:20:13 | 显示全部楼层
本帖最后由 牢固 于 2013-5-23 23:46 编辑

剪裁块的剪裁边界开关通用函数:
  1. ;;(gxl-EnableXclip ename Flag) 开关剪裁块边界,
  2. ;; ename = 剪裁块图元
  3. ;; Flag = 1  打开, = 0 关闭
  4. ;;(gxl-EnableXclip (car(entsel)) 1) ;_ Flag修剪边界
  5. (defun gxl-EnableXclip (ename Flag / IsXClip el)
  6.   ;;判断图元是否为剪裁块
  7.   (defun IsXClip (ename / xdict)
  8.     (if
  9.       (setq xdict (cdr (assoc 360 (entget ename))))
  10.        (IsXClip xdict)
  11.        (if
  12.          (eq "SPATIAL_FILTER"
  13.                (cdr (assoc 0 (setq ename (entget ename))))
  14.                )
  15.           ename
  16.           )
  17.        )
  18.     )
  19.   (if (setq el (IsXClip ename))
  20.     (progn
  21.     (entmod (subst (cons 71 Flag) (assoc 71 el) el))
  22.     (entupd ename)
  23.     )
  24.     )
  25.   )
  26. ;;测试命令
  27. ;;关闭修剪
  28. (defun c:tt ()
  29.   (while
  30.     (setq e (car (entsel "\n选择剪裁块:")))
  31.   (gxl-EnableXclip e 0)
  32.     )
  33.   (princ)
  34.   )
  35. ;;打开剪裁边界
  36. (defun c:tt ()
  37.   (while
  38.     (setq e (car (entsel "\n选择剪裁块:")))
  39.   (gxl-EnableXclip e 1)
  40.     )
  41.   (princ)
  42.   )

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-23 22:49:05 | 显示全部楼层
XDSoft 发表于 2013-5-23 21:38
AutoCAD允许用户Filter被引用对象

Filter通过抽象类AcDbFilter类实现,根 ...

看了这篇高论,才真正了解了Xclip到底是怎么工作的!才知道判断是不是剪裁块时不光要判断出"SPATIAL_FILTER"对象,还要判断该对象的71组码是否为1,若71组码为0,则剪裁块不被剪裁!
根据这个原理,我们很容易通过修改71组码值就能移除剪裁块的剪裁状态,而不必通过XClip命令来修改剪裁块的剪裁状态!



                               
登录/注册后可看大图



[pcode=lisp,true];;移除剪裁块的剪裁边界
;;(gxl-RemoveXclip (car(entsel)))
(defun gxl-RemoveXclip (ename / IsXClip el)
  ;;判断图元是否为剪裁块
  (defun IsXClip (ename / xdict)
    (if
      (setq xdict (cdr (assoc 360 (entget ename))))
       (IsXClip xdict)
       (if
         (and
           (eq "SPATIAL_FILTER"
               (cdr (assoc 0 (setq ename (entget ename))))
               )
           (eq 1 (cdr (assoc 71 ename)))
           )
          ename
          )
       )
    )
  (if (setq el (IsXClip ename))
    (progn
    (entmod (subst (cons 71 0) (cons 71 1) el))
    (entupd ename)
    )
    )
  )
;;测试命令
(defun c:tt ()
  (while
    (setq e (car (entsel "\n选择剪裁块:")))
  (gxl-RemoveXclip e)
    )
  (princ)
  )[/pcode]

评分

参与人数 1D豆 +10 收起 理由
XDSoft + 10 有始有终奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-5-22 22:13:20 | 显示全部楼层
本帖最后由 Lispboy 于 2013-5-22 22:16 编辑

QQ截图20130522220937.png

[pcode=lisp,true]
(defun get-xclip-pnt ( ename / ename2 data )
    (while (setq ename2 (cdr (assoc 360 (entget ename)))) (setq ename ename2))
   
    (if (member '(0 . "SPATIAL_FILTER") (setq data (entget ename)))
        (cons
            (eq 1 (cdr (assoc 71 data)))
            (apply 'append
                (mapcar
                    (function (lambda ( x ) (if (eq 10 (car x)) (list (cdr x)))))
                    data
                )
            )
        )
    )
)
[/pcode]

  1. (setq a (<span style="background-color: rgb(255, 255, 255);">get-xclip-pnt</span> (car (entsel))))

  2. 选择对象: (T (1117.1 700.739 0.0) (1117.1 620.156 0.0) (1058.16 620.156 0.0)
  3. (1058.16 508.579 0.0) (1303.21 508.579 0.0) (1303.21 397.002 0.0) (955.798
  4. 397.002 0.0) (955.798 700.739 0.0))

评分

参与人数 1D豆 +2 收起 理由
炫翔 + 2 及时回复奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-5-22 22:38:25 来自手机 | 显示全部楼层
Lispboy 发表于 2013-5-22 22:13
(defun get-xclip-pnt ( ename / ename2 data )
    (while (setq ename2 (cdr (assoc 360 (entget  ...

这个结果是错误的,并不是剪裁边界的真正坐标位置!示例中1 2 3 4得到的坐标是一样的!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 345个

财富等级: 日进斗金

发表于 2013-5-22 22:53:44 | 显示全部楼层
[pcode=lisp,true];; Based on code by John Uhden 4/16/2005.
;; Argument: a block reference ename or vla-object.
;; Returns: the xclip boundary WCS point list if the block is clipped,
;; otherwise nil.
(defun getclipboundary (obj / xdict filter spatial elst ptlst)
  (if (= (type obj) 'ename)
    (setq obj (vlax-ename->vla-object obj))
  )
  (setq elst (vl-catch-all-apply '(lambda ()
                                    (setq xdict (vla-getextensiondictionary obj))
                                    (setq filter (vla-getobject xdict "ACAD_FILTER"))
                                    (setq spatial (vla-getobject filter "SPATIAL"))
                                    (entget (vlax-vla-object->ename spatial))
                                  )
             )
  )                                       ; (princ elst)
                                       ; (princ "n")
  (if (not (vl-catch-all-error-p elst))
    (foreach x elst
      (if (eq 10 (car x))
        (setq ptlst (cons (cdr x) ptlst))
      )
    )
  )
  ptlst
)


[/pcode]

评分

参与人数 1D豆 +2 收起 理由
炫翔 + 2 及时回复奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-5-22 23:03:35 | 显示全部楼层
Lisper 发表于 2013-5-22 22:38
这个结果是错误的,并不是剪裁边界的真正坐标位置!示例中1 2 3 4得到的坐标是一样的!

应该有矩阵转换在里面,我研究研究。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-5-22 23:04:23 来自手机 | 显示全部楼层
userzhl 发表于 2013-5-22 22:53
;; Based on code by John Uhden 4/16/2005.
;; Argument: a block reference ename or vla-object.
;; R ...

代码和二楼的结果一样,只是得到了词典里的顶点坐标,并不是实际边界坐标!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-5-22 23:09:46 | 显示全部楼层
Lisper 发表于 2013-5-22 23:04
代码和二楼的结果一样,只是得到了词典里的顶点坐标,并不是实际边界坐标!

得先确定词典里面的坐标到底是什么坐标?我把图块移动到0,0,0插入,得到的结果也不是。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-5-22 23:18:53 来自手机 | 显示全部楼层
Lispboy 发表于 2013-5-22 23:09
得先确定词典里面的坐标到底是什么坐标?我把图块移动到0,0,0插入,得到的结果也不是。

原始剪裁的xclip,词典中坐标数据就是边界,但是进行平移后就不对了!词典数据和原始剪裁块一样,这个就很奇怪,不知道机关在哪儿?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-23 11:01:26 | 显示全部楼层
那个储存左边是创建CLIP时候的坐标信息,可惜XCLIP的轮廓CAD没有提供太多的信息,而且一炸开轮廓自动消失,但是也不是完全没有办法:提供一个思路可以用WMFout wmfin的方法,再与XCLIP储存的那个轮廓进行融合,不过会有一些小的误差
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-23 14:57:12 | 显示全部楼层
DXF Code 40 是这样解释的

按列主要次序写出的 4x3 转换矩阵。此矩阵是原始块参照(插入图元)转换的反向矩阵。原始块参照转换是重生成块参照时(始终为 12 个条目)适用于块中所有图元的参照

这个边界应该是对应 Blockdef 后有个矩阵转换而来
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-23 16:13:13 | 显示全部楼层
本帖最后由 牢固 于 2013-5-24 12:35 编辑

;;计算XCLIP的边框 By Gu_xl 2013.05.23
;;关于矩阵计算函数 参见高飞鸟的帖子 ,Lisp论矩阵
  1. (defun c:tt (/ E EE EL PL DXF40 N EEL SCALE ROTATE MOVE M0 M1)
  2.   (setq e (car (entsel)))
  3.   (setq ee e)
  4.   (while (setq e (cdr (assoc 360 (setq el (entget e))))))
  5.   (if (and          (= "SPATIAL_FILTER" (cdr (assoc 0 el)))
  6.           (= 1 (cdr (assoc 71 el)))
  7.       )
  8.     (progn
  9.       (setq pl     (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) el))
  10.             dxf40  (vl-remove-if-not '(lambda (x) (= (car x) 40)) el)
  11.             n (cdr (assoc 70 el))
  12.             eel (entget ee)
  13.             scale  (list (cdr (assoc 41 eel)) (cdr (assoc 42 eel)) (cdr (assoc 43 eel)))
  14.             rotate (cdr (assoc 50 eel))
  15.             move   (cdr (assoc 10 eel))
  16.             )      (if (= 1 (cdr (assoc 72 el))) (setq dxf40 (cdr dxf40)))
  17.       (setq m0
  18.              (list
  19.                (mapcar 'cdr
  20.                        (list (nth 0 dxf40)
  21.                              (nth 1 dxf40)
  22.                              (nth 2 dxf40)
  23.                              (nth 3 dxf40)
  24.                              )
  25.                        )
  26.                (mapcar 'cdr
  27.                        (list (nth 4 dxf40)
  28.                              (nth 5 dxf40)
  29.                              (nth 6 dxf40)
  30.                              (nth 7 dxf40)
  31.                              )
  32.                        )
  33.                (mapcar 'cdr
  34.                        (list (nth 8 dxf40)
  35.                              (nth 9 dxf40)
  36.                              (nth 10 dxf40)
  37.                              (nth 11 dxf40)
  38.                              )
  39.                        )
  40.                '(0 0 0 1)
  41.                )
  42.             )
  43.       (if (= 2 n)
  44.         (setq pl
  45.           (list (car pl)
  46.                 (list (caar pl) (cadadr pl) (caddar pl))
  47.                 (cadr pl)
  48.                 (list (caadr pl) (cadar pl) (caddar pl))
  49.                 )
  50.           )
  51.         pl
  52.         )
  53.       (setq m1 (apply 'MAT:DISPTOMATRIX (MAT:RefGeom ee)))
  54.       (setq
  55.         pl (mapcar '(lambda (x) (mat:mxp (mat:mxm m1 m0) x))
  56.                    pl
  57.                    )
  58.         )
  59.       ;;绘制边框
  60.       (command "pline")
  61.       (foreach a pl (command "_non" (trans a 0 1)))
  62.       (command "c")
  63.       (princ)
  64.       )
  65.     )
  66.   )



评分

参与人数 1D豆 +10 收起 理由
eachy + 10 有始有终奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-5-23 21:38:43 | 显示全部楼层


AutoCAD允许用户Filter被引用对象

Filter通过抽象类AcDbFilter类实现,根据ObjectARX文档,有两种Filter方式:AcDbLayerFilter和AcDbSpatialFilter。只有AcDbSpatialFilter用于AutoCAD 2000+版本,而层Filter只能在第三方应用程序中用到,或根本不能工作。


空间Filter

      空间Filter定义了一个3D空间,这个所谓的剪切空间是由平面多边曲线和与之相关的高度生成的。因此,空间总是N边的棱柱。

如果被引用块容器的所有对象完全包含在这个空间中,就会被显示出来;如果完全不包含在这个空间中,就不会被显示出来。所有其他对象将被分为可视部分(在剪切空间内)和不可视部分(不在剪切空间内)。

AcDbSpatialFilter对象位于块引用对象的扩展词典中,在这个扩展中,可以发现关键字“
ACAD_FILTER",它指向另外一个词典,在第二个词典中,用户可通过关键字”SPATIAL"来访问AcDbSpatialFilter对象。


剪切空间是一个拉伸成的平面多边曲线。因此,要定义空间,必须用
局部坐标系来定义多边形的平面。这是通过使用平面沿高度的法线方向(在ObjectDBX中)或者平面上的点实现的(在AutoLISP和DXF中)。

ObjectDBX
Activex Automation
DXF/AutoLISP
getDefinition(),normal
n/a
组210
getDefinition(),elavation
n/a
n/a
n/a
n/a
组11,局部坐标系的原点


剪切多边形在该局部坐标系的X/Y平面内,它是通过两个或更多的2D点定义的。如果只有两个点,则这两个点定义了一个矩形。

也许你会说,两个点在任何平面可以定义许多矩形。是的,至少还需要定义个旋转角度或者矩形的方向。然而由于某种原因,AutoCAD不记录这样的旋转。相反,它记录引用块的坐标系和局部坐标系之间的整个转换矩阵(换句话说,定义在组码40的矩阵是剪切空间坐标系到引用块的变换矩阵)。

转换矩阵是个4*4的矩阵,每个源点与矩阵相乘,以获得转换点(转换到块定义坐标系),每个点按下式计算:
p1=T*p

因为这种转换矩阵的最后一行总是(0 0 0 1),所以AutoCAD只记录前三行。在DXF和AutoLISP中,会发现如下顺序列出的12个数值:第一行从左到右,第二行从左到右,第三行从左到右。

ObjectDBX
Activex Automation
DXF/AutoLISP
n/a
n/a
组40,局部坐标系转换矩阵

回顾剪切多边形。现在已经有了局部坐标系,多边形要么由两个2D点定义(创建一个平行于坐标系的矩形),要么由任意多的2D点构成。在第二种情况下,点由直线顺序地连接起来,形成封闭的多边形。


ObjectDBX
Activex Automation
DXF/AutoLISP
n/a
n/a
组70,点的数量
getDefinition(),points
n/a
组10

与剪切平面相垂直,剪切空间可以在一个或两个方向上有边界,也可以两个方向上都没有边界。每个边界是通过到平面的距离给定的,沿法线方向测量

ObjectDBX
Activex Automation
DXF/AutoLISP
n/a
n/a
组72,有上边界
getDefinition(),frontClip
n/a
组40,上边界距离
n/a
n/a
组73,有下边界
n/a
n/a
组41,下边界距离

不是每个块插入都被过滤,即使扩展词典指向一个AcDbSpatialFilter对象也是如此,一个单独的标志指出显示是否应该被剪切。

ObjectDBX
Activex Automation
DXF/AutoLISP
getDefinition(),enabled
n/a
组71

剪切多边形和它的上下边界都是以引用块的坐标系统表示的。任何转换、旋转、缩放和其他类似操作都已经得以应用。(也就是说上面说的局部坐标系的变换矩阵已经包含了引用块的变换)。


在某些情况下,可能会需要计算剪切空间的边角,就像它们出现在被引用块的坐标系一样,事实上,这就是应该产生过滤的地方。要将剪切空间从引用块转换到被引用块,需要做与插入块相反的工作。


按数学术语来说,我们需要所有转换的逆,或最终块转换矩阵的逆。在DXF和AutoLISP中,这个逆转换矩阵在另外一套12组40值中。就如同前面介绍的矩阵,第四行包含(0 0 0 1),也被忽略了。(这主要是在AUTOCAD最初硬件很紧张情况下为了节省存储空间)。


ObjectDBX
Activex Automation
DXF/AutoLISP
n/a
n/a
组40,逆块转换矩阵



总结:

对于一个典型的SPATIAL_FILTER的entget数据结构

  1. ((0 . "SPATIAL_FILTER") (100 . "AcDbFilter") (100 . "AcDbSpatialFilter") (70 .
  2. 4) (10 415.361 83.0325 0.0) (10 480.678 83.0325 0.0) (10 480.678 15.6616 0.0)
  3. (10 415.361 15.6616 0.0) (210 0.0 0.0 1.0) (11 0.0 0.0 0.0) (71 . 1) (72 . 0)
  4. (73 . 0) (40 . -0.61694) (40 . -0.78701) (40 . 0.0) (40 . 319.661) (40 .
  5. 0.78701) (40 . -0.61694) (40 . 0.0) (40 . -314.787) (40 . 0.0) (40 . 0.0) (40 .
  6. 1.0) (40 . 0.0) (40 . 1.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 .
  7. 1.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 1.0) (40 . 0.0))
复制代码


解释如下:


AcDbSpaitalFilter的DXF类名是“SPATIAL_FILTER"。接在通常的AcDbObject组后面的是子类标识,然后是组70,10(重复)、210、11、71、72、40(上边界距离)、73、41、40(局部坐标系转换矩阵,重复12次)、和40(逆块转换,重复12次)。

应用实例:

求下图XCLIP的边界


QQ截图20130523211315.png

[pcode=lisp,true]
(defun GetSpatialFilter (ename / Data Dict tempDict)
    ; Get the xclip boundry   
    (if
        (and
            (setq Data (entget ename))
            (setq Dict (cdr (assoc 360 Data)))
            (setq tempDict (dictsearch Dict "ACAD_FILTER"))
            (setq tempDict (dictsearch (cdr (assoc -1 tempDict)) "SPATIAL"))
        )
        (cons '(0 . "SPATIAL_FILTER") (member (assoc 100 tempDict) tempDict))
    )
)
[/pcode]

获得块的SpatialFilter数据

  1. 命令: (setq a (GetSpatialFilter (car (entsel))))

  2. 选择对象: ((0 . "SPATIAL_FILTER") (100 . "AcDbFilter") (100 .
  3. "AcDbSpatialFilter") (70 . 4) (10 415.361 83.0325 0.0) (10 480.678 83.0325 0.0)
  4. (10 480.678 15.6616 0.0) (10 415.361 15.6616 0.0) (210 0.0 0.0 1.0) (11 0.0 0.0
  5. 0.0) (71 . 1) (72 . 0) (73 . 0) (40 . -0.61694) (40 . -0.78701) (40 . 0.0) (40
  6. . 319.661) (40 . 0.78701) (40 . -0.61694) (40 . 0.0) (40 . -314.787) (40 . 0.0)
  7. (40 . 0.0) (40 . 1.0) (40 . 0.0) (40 . 1.0) (40 . 0.0) (40 . 0.0) (40 . 0.0)
  8. (40 . 0.0) (40 . 1.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 1.0)
  9. (40 . 0.0))
[pcode=lisp,true]
(defun XD::List:GetDataByInterval(l c1 c2 tf / info re x)
   (setq re  (member (assoc c1 l) (reverse (cdr (member (assoc c2 l) (reverse info))))))
   (if tf
      (setq re (mapcar '(lambda(x)(cdr x)) re))
   )
   re
)
(defun XD::List:GetDataBySums (l c s / d el i)
  (if (and
        (cond
          ((= (type c) 'INT)
            (setq d (assoc c l))
          )
          ((= (type c) 'LIST)
            T
          )
          (t
            nil
          )
        )
        (setq d (member d l))
      )
    (progn
      (setq i 0)
      (repeat s
        (setq el (cons (nth i d) el))
        (setq i (1+ i))
      )
    )
  )
  (reverse el)
)
(defun XD:GetSpatialInfo (e / _spatialMat bb bound coords d d1 i info mat mat1 mat2 mat3 mat4 normal orin pnt pnts rmat ub zaxis)
  (defun _spatialMat (mat / d d1 i mat1 mat2 mat3 mat4 enabled)
    (setq i 0)
    (repeat 12
      (setq d (nth i mat))
      (cond
        ((and
           (>= i 0)
           (< i 4)
         )
          (setq d1 (cdr d)
                mat1 (cons d1 mat1)
          )
        )
        ((and
           (>= i 4)
           (< i 8)
         )
          (setq d1 (cdr d)
                mat2 (cons d1 mat2)
          )
        )
        (t
          (setq d1 (cdr d)
                mat3 (cons d1 mat3)
          )
        )
      )
      (setq i (1+ i))
    )
    (list (reverse mat1) (reverse mat2) (reverse mat3) '(0.0 0.0 0.0 1.0))
  )
  (if (setq info (GetSpatialFilter e))
    (progn
      (setq orin (cdr (assoc 11 info)) ;               orin (cons "Orin" orin)
            enabled (cdr (assoc 71 info))
            Enabled (cons "Enabled" enabled)
            normal (assoc 210 info)
            zAxis (cons "zAxis" (cdr (assoc 210 info)))
            Coords (cons "Coords" (list orin (cdr zAxis)))
            pnts (assoc 70 info)
            pnt (list "PntSums" (cdr pnts))
            pnts (XD::List:GetDataByInterval info 70 210 t)
            pnts (cons "Pnts" (cdr pnts))
            uB (cdr (assoc 72 info))
            ub (cond
                 ((= 72 1)
                   (cdr (cdr (member uB info)))
                 )
                 (t
                   0.0
                 )
               )
            bB (cdr (assoc 73 info))
            bb (cond
                 ((= 73 1)
                   (cdr (cdr (member bB info)))
                 )
                 (t
                   0.0
                 )
               )
            bound (list "Bound" ub bb)
            mat (XD::List:GetDataBySums info 40 24)
            mat1 (XD::List:GetDataBySums mat 40 12)
            mat2 (reverse (XD::List:GetDataBySums (reverse mat) 40 12))
            mat1 (_spatialMat mat1)
            Mat (cons "Mat" mat1)
            mat2 (_spatialMat mat2)
            rMat (cons "rMat" mat2)
      )
    )
  )
  (list Enabled Coords pnt pnts bound mat rmat)
)[/pcode]

QQ截图20130523211245.png

1、函数GetSpatialInfo获得块XCLIP的基本信息,关联表:

Enabled---裁剪是否启用
coords---局部坐标系(原点,Z轴)
PntSums-- 剪切多边形顶点数(如果是2,我们还需计算出矩形的4个顶点)
Pnts-----多边形顶点表(定义在局部坐标系下)
Bound---上下边界数据,0表示无边界
Mat----剪切空间局部坐标系到块定义的转换矩阵
rMat---逆块矩阵


通用纯LISP函数,见附件


请点击此处下载

查看状态:需购买或无权限

您的用户组是:游客

文件名称:GetSpatialFilter.lsp 
下载次数:34  文件大小:3.92 KB 
下载权限: 不限 以上  [免费赚D豆]




[pcode=lisp,true]命令: (setq info (XD:GetSpatialInfo e))
(("Enabled" . 1) ("Coords" (0.0 0.0 0.0) (0.0 0.0 1.0)) ("PntSums" 4) ("Pnts"
(415.361 83.0325 0.0) (480.678 83.0325 0.0) (480.678 15.6616 0.0) (415.361
15.6616 0.0)) ("Bound" 0.0 0.0) ("Mat" (-0.61694 -0.78701 0.0 319.661) (0.78701
-0.61694 0.0 -314.787) (0.0 0.0 1.0 0.0) (0.0 0.0 0.0 1.0)) ("rMat" (1.0 0.0
0.0 0.0) (0.0 1.0 0.0 0.0) (0.0 0.0 1.0 0.0) (0.0 0.0 0.0 1.0)))

[/pcode]

典型数据如下:

[pcode=lisp,true]命令: (setq pnts (cdr (assoc "Pnts" info)))
((415.361 83.0325 0.0) (480.678 83.0325 0.0) (480.678 15.6616 0.0) (415.361
15.6616 0.0))
[/pcode]
2、我们用上面的四个点画出剪切空间的多边形,上图的黄线。

[pcode=lisp,true]命令: (setq mat (cdr (assoc "Mat" info)))
((-0.61694 -0.78701 0.0 319.661) (0.78701 -0.61694 0.0 -314.787) (0.0 0.0 1.0
0.0) (0.0 0.0 0.0 1.0))[/pcode]

[pcode=lisp,true]
(setq pnts1 ($xdlsp_points_transform pnts mat))
((-1.93974 -39.1196 0.0) (-42.2365 12.2856 0.0) (10.7852 53.8495 0.0) (51.0819
2.44432 0.0))
[/pcode]

3、得到剪切空间到块定义的变换矩阵,矩阵作用到上面的四个点,得到红色的多边形,这个转换到块定义的坐标系了。

[pcode=lisp,true]命令: (setq mat_blk2wcs (xdrx_matrix_block2wcs e))
((-0.61694 1.57402 0.0 322.162) (-0.78701 -1.23388 0.0 218.892) (0.0 0.0 1.0
0.0) (0.0 0.0 0.0 1.0))
[/pcode]

4、 上面代码得到块定义到模型空间块引用(INSERT)实体的变换矩阵,作用上面红色四个点,得到模型空间的最终的“裁剪边界”。

[pcode=lisp,true]
(setq pnts2 ($xdlsp_points_transform pnts1 mat_blk2wcs))
((261.784 268.688 0.0) (367.557 236.974 0.0) (400.269 143.96 0.0) (294.495
175.674 0.0))

[/pcode]

有了上面的分析和写的LISP函数,写个测试命令就很简单了,矩阵变换可以使用高飞鸟版主的矩阵函数,我使用了XDRX_API的矩阵函数做演示


                               
登录/注册后可看大图


[pcode=lisp,true]
(defun c:tt ( / clr e info mat1 mat2 p1 p2 p3 p4 pnts pnts1 pnts2 v)
  (defun _dl (pnts clr)
    (apply
      'command
      (cons "pline" pnts)
    )
    (command "c")
    (xdrx_polyline_setconstantwidth (entlast) 4.0)
    (xdrx_entity_setcolor (entlast) clr)
  )
  (if (setq e (car (entsel)))
    (progn
      (setq info (xd:getspatialinfo e)
            pnts (cdr (assoc "Pnts" info)) ; 得到剪切空间的点表
            mat1 (cdr (assoc "Mat" info)) ; 得到剪切空间到块容器坐标系的变换矩阵
            mat2 (xdrx_matrix_block2wcs e) ; 得到块容器坐标系到世界坐标系的变换矩阵
      )
      (if (= 2 (length pnts))               ; 如果是2点,算出矩形
        (progn
          (setq p1 (car pnts1)
                p3 (cadr pnts1)
                v (mapcar '- p3 p1)
                p2 (mapcar '+ p1 (list (car v) 0 0))
                p4 (mapcar '+ p1 (list 0 (cadr v) 0))
                pnts (list p1 p2 p3 p4)
          )
        )
      )
      (_dl pnts 2) ;;画剪切空间多边形
      (setq pnts1 ($xdlsp_points_transform pnts mat1)) ; 剪切空间点变换到块空间
      (_dl pnts1 1);;画块定义空间裁剪多边形
      (setq pnts2 ($xdlsp_points_transform pnts1 mat2))        ; 块空间点变换到模型空间块引用
      (_dl pnts2 6);;画模型空间INSERT最终裁剪边界
    )
  )
  (princ)
)

[/pcode]






评分

参与人数 2威望 +4 D豆 +10 贡献 +2 收起 理由
Highflybird + 3 + 5 + 1 很给力!经验;技术要点;资料分享奖!
牢固 + 1 + 5 + 1 技术引导讨论和指点奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-5-23 22:39:29 | 显示全部楼层
WOW,这矩阵太神奇,文章太经典。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-19 18:34 , Processed in 0.556547 second(s), 67 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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