- UID
- 1
- 积分
- 15926
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-3
- 最后登录
- 1970-1-1
|
楼主 |
发表于 2013-5-10 16:56:15
|
显示全部楼层
[pcode=lisp,true]
;;判断BLOCK定义中是否已有wipeout
(defun $xdob_Block_hasWipeout (blkname / e has)
(setq has nil)
(if (xdrx_object_get "block" blkname)
(progn
(while (and
(not has)
(setq e (xdrx_object_next))
)
(if (= "AcDbWipeout" (car e))
(setq has t)
)
)
)
)
has
)
;;对象表、选择集删除
(defun $xdlsp_object_delete (el / e el1 ss x)
(cond
((= (type el) 'ename)
(mapcar
'(lambda (x)
(xdrx_object_delete x)
)
el
)
)
((= 'pickset el)
(xdrx_setsstodb ss 0)
(while (setq e (xdrx_getentdxf 0))
(xdrx_object_delete e)
)
)
)
)
;;主函数,给现有的BLOCK定义,添加wipeout实体,并放入块容器最前面(避免遮罩自身块内实体)
(defun $XDOB_Block_AppendWipeout (blkname tf / box e el el1 el2 ob x)
(if (and
(setq ob (xdrx_object_get "block" blkname)) ;;得到BLOCK 对象块容器对象
(not ($xdob_block_haswipeout blkname)) ;; 判断是否已经制作过wipeout
)
(progn
(while (setq e (xdrx_object_next)) ;;遍历块容器得到所有块内实体并copy到模型空间
(setq e (cadr e))
(setq el1 (cons e el))
(xdrx_entity_transformedcopy e $xdtb_matrix_mat0)
(setq el2 (cons (entlast) el2))
)
(setq el1 (reverse el1)
el2 (reverse el2)
)
($XDLSP_Object_Delete el1) ;;删除块内的实体,清空块,以便在第一个位置插入wipeout
(setq box (apply
'xdrx_entity_box ;;实体包围盒
el2
)
)
($xdlsp_makewipeout box) ;;制作wipeout
(mapcar
'(lambda (x)
(xdrx_block_append_entity blkname x) ;;wipeout第一,然后依次插入原来的块内实体。
)
(setq el2 (cons (entlast) el2))
)
(xdrx_object_delete el2) ;; 删除临时copy的实体。
(if tf
(command ".wipeout" "f" "off") ;; 根据开关变量,是否显示wipeout外框
)
)
)
t
)
[/pcode]
测试命令:
[pcode=lisp,true]
(defun c:t5 ( / blkname e e1 from_coord mat p1 to_coord to_vx to_vy to_vz)
(if (and
(setq e (car (xdrx_entsel "\n拾取插入块<退出>:" '((0 . "INSERT"))))) ;;支持filter的xdrx_entsel
(setq blkname (xdrx_getentdxf 2)) ;;得到块名
($xdob_block_appendwipeout blkname t) ;; 制作遮罩块,不显示边框。
)
(progn
(while (and
(setq e1 (xdrx_entsel "\n拾取插入的曲线<退出>:" '((0 . "*line,arc,circle,ellipse")))) ;;拾取曲线实体
(setq p1 (xdrx_curve_closestpoint (car e1) (cadr e1))) ;;保证点在曲线上,最近点。
)
(setq p1 (last p1)
from_coord ($xdlsp_entity_getecscoordsystem e) ;; 得到插入块的 “源实体坐标系"
to_vx (xdrx_curve_getfirstderiv (car e1) p1) ;;目标坐标系的X轴
to_vy (xdrx_vector_perpvector to_vx) ;;目标坐标系的Y轴
to_vz (xdrx_vector_crossproduct to_vx to_vy) ;;目标坐标系的Z轴
to_coord (list (cadr e1) to_vx to_vy to_vz) ;;向量叉乘得到Z轴
mat (xdrx_matrix_aligncoordsystem from_coord to_coord) ;;求得源坐标系到目标坐标系的变换矩阵
)
(xdrx_entity_transformedcopy e mat);; 作用到实体上,完成一个对齐的插入块。
)
)
)
(princ)
)
[/pcode]
添加wipeout到块定义编程要点如下:
1、往BLOCK定义中添加wipeout实体,由于draworder对除模型空间外的其他块表容器不起作用,所以我们一定要把wipeout放入块定义的第一个实体。本程序只是简单的求块内所有实体的“包围盒”制作wipeout,具体特定的应用也可以找轮廓线等制作精确的wipeout。
2、如果做到1呢? 程序中把块定义所有实体Transform Copy 出来,然后删除掉块定义中的所有实体后,添加wipeout实体到块定义中。添加后,在一次把Copy出的实体添加回块表容器中。
测试命令T5的编程要点:
1、程序没有用到 sachindkini 朋友提供的LEE-MAC的角度法在曲线上插入块,还是使用了矩阵的方法,主要还是让大家理解矩阵的方便。
2、这个程序里面,没有用以前介绍的,求各种中间矩阵,然后用矩阵组合,最后应用矩阵到块的方法,介绍了另外一种更方便的矩阵方法,就是直接从一个坐标系到另一个坐标的变换方法。
3、图块INSERT的实体坐标系如图:
我们通过函数
[pcode=lisp,true]
(defun $XDLSP_Entity_GetEcsCoordSystem(e / m_w2u oldcmd)
(setq oldcmd (getvar "cmdecho"))
(command "ucs" "Object" e)
(setq m_w2u (xdrx_matrix_ucs2wcs))
(command "ucs" "p")
(setvar "cmdecho" oldcmd)
($xdlsp_matrix_getCoordSystem m_w2u)
)
[/pcode]
- 命令: ($XDLSP_Entity_GetEcsCoordSystem (car (entsel)))
- 选择对象: ((707.705 -42.4508 0.0) (1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
复制代码 上面返回值说明: car --实体坐标系的原点坐标(WCS)
'(1 0 0)----实体坐标系的X轴向量
'(0 1.0 0.0)----实体坐标系的Y轴向量
'(0.0 0.0 1.0)--实体坐标系的Z轴向量
实体坐标系的表示方式就是 from = '(原点 X轴向量 Y轴向量 Z轴向量)
考虑到图块的插入点不一定是图块的中心,所以我们求了图块实体的包围盒的中点(WCS),作为坐标系的原点(因为我们要按照中点去插入曲线上)。
4、曲线插入点位置的UCS坐标系,如图
这个坐标系是如何得到的尼?
代码:
[pcode=lisp,true]
(setq to_vx (xdrx_curve_getfirstderiv (car e1) p1)
to_vy (xdrx_vector_perpvector to_vx)
to_vz (xdrx_vector_crossproduct to_vx to_vy)
to_coord (list (cadr e1) to_vx to_vy to_vz)
)
[/pcode]
过程手动演示如图:
解释:
- a. 得到曲线在插入点的一阶导数的单位向量(也就是曲线在该点的切向量to_VX),即UCS的X轴。
- b. 求向量to_VX的切向量(VerpVector)得到to_VY,即UCS的Y轴。
- c. to_VX 和VY 向量叉乘得到VZ,即UCS的Z轴。
- d. 和插入点的WCS坐标一起,就得到了UCS的坐标系表达 to <--- (插入点 to_x to_y to_z)
复制代码 现在得到了变换前的原坐标系 from_coord ,也得到了目标坐标系 to_coord
下面用XDRX_API的从一个坐标系到另一个坐标系的变换矩阵函数xdrx_matrix_alignCoordSystem
[pcode=lisp,true]
(setq mat (xdrx_matrix_alignCoordSystem from_coord to_coord))
[/pcode]
这样直接根据两个坐标系就直接得到了变换矩阵,而省略了以前需要在各自坐标系还需要的额外的变换。
最后用XDRX_API实体矩阵COPY函数: xdrx_entity_transFromedCopy 得到了一份坐标系对齐的实体(插入的WIPEOUT块)。
[pcode=lisp,true]
(xdrx_entity_transformedcopy e mat)
[/pcode]
源坐标系和目标坐标系,都是相对WCS坐标系定义的,就是他们的原点都是WCS下的点。
上面说了那么多,其实看到程序代码也就几行。思路清晰,矩阵构造准确,程序很容易写。
不清楚的,可以跟帖研讨坐标系间变换矩阵的方法。
XDRX_API 16 版本下载地址: http://bbs.xdcad.net/forum.php?mod=viewthread&tid=667981
|
评分
-
查看全部评分
|