highflybir 发表于 2011-11-16 22:12:10

【飞鸟集】心随我动--为LISP定制的动态输入,拖拉和动态信息函数(更新至20130731)

本帖最后由 highflybir 于 2013-8-1 09:09 编辑

源码已经贴在ObjectArx版块处!!
http://bbs.mjtd.com/thread-90552-1-1.html
arx程序和LISP样例:

===========================================
2013.07.31日作重大更新新
把函数全部加上前缀 HFB_
增添了一些函数:
1、对图功能
C:CompareDwgs
2、状态栏开关函数
C:ShowDrawingStatusBar
3、进度条函数
HFB_SetProgressMeter
HFB_SetProgressMeterPos
4、带关键字回调的SSGet
HFB_SSGet
HFB_InitGet
HFB_SSFree
另外,对JIG,Monitor和Hook以及定时器事件都进行了优化和改进。
===========================================
12.9日更新,先附上beta版本,等各位测试后没问题,再替换。
增加了开关函数。具体演示如下:

===========================================
12.4更新,修正了动态输入的问题。消除了可能引起异常的几个bug.
增加了英文版本。
===========================================
11.29更新,修正了几个bug。增加了钩子和定时器。请重新下载新的arx和LISP.
现在可以卸载时候不弹出对话框和使得CAD崩溃了。
(setLIsptimer 回调函数 毫秒数)    ;增加一个定时器事件
(KillLispTimer)   ;关闭定时器
(RegisterHook回调函数);注册一个钩子
(removeHook)   ;移除钩子
===========================================
11.21更新,增加了R2000-2002版本。增加了几个新的函数。请重新下载新的arx和LISP.
(GetAperture)   ;靶框下的图元列表
(GetOSMode)   ;当前的捕捉模式(非系统变量)
(GetNested)      ;嵌套选择的图元列表
===========================================
ARX已经更新,有反映R2004不能用的请重新下载,并请反馈测试结果。
新增加R2007,R2008,R2009的64位版本。(dynArxFor2007-2009x64.arx)
===========================================
虽说LISP中已经提供了动态的输入采集函数grread,然而这个函数有诸多不足,譬如不支持捕捉,正交及动态输入。不能在图形外的菜单等处操作。等等。
而且在一定情况下受速度限制。
为此,我特意编写了几个函数,极大程度地扩张了CAD的动态函数。
有了这几个函数,你就可以自由地拖拉物体,既支持捕捉,也支持正交,等等。
还可以定制自己的tooltip(热信息),定制自己的光标(这个光标可以是CAD的任何图元);
可以随时采集输入信息,甚至可以让GetPoint,SSGet之类的函数能带有回调。

用法,先依据自己的CAD版本,加载相应的arx,然后运行附件中的测试样例。

说明:
这个arx提供了四个主要函数 HFB_PointMonitor, SSJIG , DragGen , XFormSS.其用法介绍参见下面的帖子。
其中以HFB_PointMonitor效果最好,SSJIG能动态输入,DragGen和XFormSS可执行大量选择集的变换。
这些函数在R2012版本上效果最好。
帖子会随时更新源码和演示,欢迎大家提意见,或者把自己的样例放上来。我会为样例加分。
在编写这个程序中,得到了FSXM的很多建议和支持,在此深表感谢。

一、输入点监视函数HFB_PointMonitor

    用来动态采集CAD中光标的位置,并反馈给用户处理。这样以来,你就可以拥有自己的鼠标。
    用来动态采集Getpoint,getangle,getdist,getorient,getcorner,entsel,nentsel,nentselp,ssget之类的函数时光标所在位置,并对其反应,形成各种特殊的效果,譬如动态拖拉,动态信息等等。
    这个函数的优点在于,回调函数不一定要在命令状态下就可以运行,就像非模态一样。


(vl-load-com)
(if (null CurDoc)
(setq CurDoc
(vla-get-ActiveDocument (vlax-get-acad-object)))
)


;;;*********************************************************************
;;;HFB_PointMonitor用法:                                                
;;;(HFB_PointMonitor [回调函数] [选择集/图元])                        
;;;不带参数的(HFB_PointMonitor)为关闭监视事件                           
;;;第一个参数为回调函数名称,应该为字符串,且存在的函数               
;;;回调函数只有一个参数,这个参数为三维点,代表你现在鼠标所在位置.如果返
;;;回值为选择集或者图元,将更改鼠标捕捉排除的物体为你返回值所代表的物体.
;;;如果返回值为字符串,说明将把字符串的信息附加到CAD的tooltip上。      
;;;第二个参数可以缺省,缺省的话,将不排除鼠标捕捉,不过你以后仍可指定.   
;;;*********************************************************************
;;;*********************************************************************
;;;图元信息显示                     
;;;*********************************************************************
(defun c:Info(/ ret)
(defun InfoCallback (dynpt / txt lst dat)
    (setq txt (vl-princ-to-string (mapcar 'rtos dynpt)))
    (setq txt (strcat "\n当前点的坐标是:" txt))
    (if (setq lst (nentselp dynpt))
      (progn
(setq dat (entget (car lst)))
      (strcat txt "\n这个图元的类型是:" (cdr (assoc 0 dat)))
      )
      txt
    )
)
(setq ret (HFB_PointMonitor "InfoCallback"))
(prompt "\n如果要关闭监视,请用函数(HFB_PointMonitor)")
(princ)
)
;;;*********************************************************************
;;;自定义光标                     
;;;*********************************************************************
(defun C:MyCursorOn(/ ret ent)      ;打开光标
(defun CursorCallback (dynpt / height insPnt)
    (if (not (vlax-erased-p txtobj))
      (progn
      (setq height (/ (getvar 'viewsize) 50))
      (setq insPnt (mapcar '+ dynpt (list (/ height 2) (/ height 2) 0)))
      (vlax-put txtobj 'InsertionPoint inspnt)
      (vlax-put txtobj 'heightheight)
      )
      (HFB_PointMonitor)
    )
)
(setq ent (entmakex
       (list
      '(0 . "text")
      '(1 . "highflybird")   
      '(62 . 3)
      (cons 10 (getvar 'lastpoint))
      (cons 40 (/ (getvar 'viewsize) 50))   ;for a standard dwg
      )
    )
)
(setq txtobj (vlax-ename->vla-object ent))
(setq ret (HFB_PointMonitor "CursorCallback" ent))
(prompt "\n如果要关闭自定义光标,请用命令MyCursorOff.")
(princ)
)
(defun C:MyCursorOff(/ ret)      ;关闭光标
(HFB_PointMonitor)
(and (not (vlax-erased-p txtobj)) (vla-erase txtobj))
(setq txtobj nil)
(princ)
)
;;;*********************************************************************
;;;带回调函数的GetXXX测试(模拟move命令)                                 
;;;*********************************************************************
(defun C:GetXXX(/ OBJLST P0 PT SS)
(setq *error*_Old *error*)      ;保存出错处理函数
(setq *error* *error*_New)      ;设置新的出错处理
(defun PointCallback (dynpt)      ;回调函数
    (foreach obj objlst
      (vla-move obj (vlax-3d-point p0) (vlax-3d-point dynpt));移动物体
    )
    (setq p0 dynpt)      
)
(vla-StartUndoMark CurDoc)      ;撤销编组开始
(if (and (setq ss (ssget))
    (setq pt (getpoint "\n第一点(1st Point): "))
      )
    (progn
      (setq objlst (GetObjects ss))
      (setq p0 (trans pt 1 0))      ;需要转化到世界坐标系
   
      ;;设置回调函数名和需要排除捕捉的选择集
      (setq ret (HFB_PointMonitor "PointCallback" ss))   ;第一个参数是回调函数名,第二个参数是可以省略(如果不需要排除捕捉的话)
      ;;现在就可以看到动态效果了
      (setq ret (getpoint pt "\n第二点(2nd point): "))   ;此处可以是lisp的交互函数,例如getpoint,getangle之类。
      ;;最后关闭监视
      (HFB_PointMonitor)      
      
      (princ ret)
    )
)
(vla-EndUndoMark curdoc)      ;编组结束
(princ)
)

xshrimp 发表于 2011-11-17 09:27:37

给力.
CAD2004加载不成功. 2006加载成功.

Gu_xl 发表于 2011-11-19 10:58:25

本帖最后由 Gu_xl 于 2013-5-20 22:54 编辑

动态信息查询,由一个经典的yad动态信息查询函数改编而来!

;;;飞鸟集]心随我动--为LISP定制的动态输入,动态拖拉和动态信息函数之应用---动态信息查询
;;;由一个经典的yad动态信息查询函数改编而来!改编: Gu_xl 2011.11.19
(defun InfoCallBak (PT /TOANG    DIS ENT)
(defun toang(ang i)
    (if (= i 1)
      (* ang (/ 180 pi))
      (* ang (/ pi 180))
    )
)
(defun gxl-dxf (ent i)
(cdr (assoc i (entget ent)))
)
(defun dis (ENT / MJBL OBJ LAYNM NAME LST)
    (if (= mjdw 1000) (setq mjbl 1000000) (setq mjbl 1))
    (setq obj (vlax-ename->vla-object ent))
    (setq laynm (strcat "图层:" (gxl-dxf ent 8)) name (gxl-dxf ent 0))
    (cond
      ((= name "3DFACE")
      (setq lst (list "【三维面】" laynm))
      )
      ((= name "3DSOLID")
      (setq lst (list "【三维实体】" laynm (strcat "格式版本号:" (itoa (gxl-dxf ent 70)))))
      )
      ((= name "ACAD_PROXY_ENTITY")
      (setq lst (list "【代理】" laynm))
      )
      ((= name "ARC")
      (setq lst (list "【圆弧】" laynm (strcat "半径:" (rtos (vla-get-radius obj) 2 0))
                                       (strcat "圆心角:" (rtos (toang (vla-get-TotalAngle obj) 1) 2 1) "度")
                                       (strcat "起始角:" (rtos (toang (vla-get-StartAngle obj) 1) 2 1) "度")
                                       (strcat "终止角:" (rtos (toang (vla-get-EndAngle obj) 1) 2 1) "度")
                                       (strcat "总弧长:" (rtos (vla-get-ArcLength obj) 2 0))
                                       (strcat "面积:" (rtos (/ (vla-get-Area obj) mjbl) 2 2) "㎡")
      ))
      )
      ((= name "ATTDEF")
      (setq lst (list "【属性定义】" laynm (strcat "标签:" (vla-get-TagString obj))
                                             (strcat "提示:" (vla-get-PromptString obj))
                                             (strcat "缺省值:" (vla-get-TextString obj))
                                             (strcat "高度:" (rtos (vla-get-Height obj) 2 0))
                                             (strcat "角度:" (rtos (toang (vla-get-Rotation obj) 1) 2 1) "度")
                                             (strcat "文字样式:" (vla-get-StyleName obj))
      ))
      )
      ((= name "ATTRIB")
      (setq lst (list "【属性】" laynm (strcat "标签:" (vla-get-TagString obj))
                                       (strcat "缺省值:" (vla-get-TextString obj))
                                       (strcat "高度:" (rtos (vla-get-Height obj) 2 0))
                                       (strcat "角度:" (rtos (toang (vla-get-Rotation obj) 1) 2 1) "度")
                                       (strcat "文字样式:" (vla-get-StyleName obj))
      ))
      )
      ((= name "BODY")
      (setq lst (list "【体】" laynm (strcat "格式版本号:" (itoa (gxl-dxf ent 70)))))
      )
      ((= name "CIRCLE")
      (setq lst (list "【圆】" laynm (strcat "半径:" (rtos (vla-get-radius obj) 2 0))
                                       (strcat "周长:" (rtos (vla-get-Circumference obj) 2 0))
                                       (strcat "面积:" (rtos (/ (vla-get-Area obj) mjbl) 2 2) "㎡")
      ))
      )
      ((= name "DIMENSION")
      (setq lst (list "【尺寸标注】" laynm (strcat "标注样式:" (vla-get-StyleName obj))
                                             (strcat "文字样式:" (vla-get-TextStyle obj))
                                             (strcat "文字高度:" (rtos (vla-get-TextHeight obj) 2 1))
                                             (strcat "替带文字:" (if (= (gxl-dxf ent 1) "") "无" (gxl-dxf ent 1)))
      ))
      )
      ((= name "ELLIPSE")
      (setq lst (list "【椭圆】" laynm (strcat "长轴半径:" (rtos (vla-get-MajorRadius obj) 2 0))
                                       (strcat "短轴半径:" (rtos (vla-get-MinorRadius obj) 2 0))
                                       (strcat "起始角:" (rtos (toang (vla-get-StartAngle obj) 1) 2 1) "度")
                                       (strcat "终止角:" (rtos (toang (vla-get-EndAngle obj) 1) 2 1) "度")
                                       (strcat "面积:" (rtos (/ (vla-get-Area obj) mjbl) 2 2) "㎡")
      ))
      )
      ((= name "HATCH")
      (setq lst (list "【图案填充】" laynm (strcat "图案名称:" (vla-get-PatternName obj))
                                             (strcat "角度:" (rtos (toang (vla-get-PatternAngle obj) 1) 2 1))
                                             (strcat "比例:" (rtos (vla-get-PatternScale obj) 2 0))
                                             (strcat "关联:" (if (= (vla-get-AssociativeHatch obj) :vlax-false) "关闭" "打开"))
                                             (strcat "填充样式:" (nth (vla-get-HatchStyle obj) '("普通" "外部" "忽略")))
      ))
      )
      ((= name "IMAGE")
      (setq lst (list "【图像】" laynm (strcat "图像大小:" (rtos (car (gxl-dxf ent 13)) 2 0) "X" (rtos (cadr (gxl-dxf ent 13)) 2 0))))
      )
      ((= name "INSERT")
      (setq lst (list "【图块】" laynm (strcat "名称:" (gxl-dxf ent 2))
                                       (strcat "X比例:" (rtos (gxl-dxf ent 41) 2 1))
                                       (strcat "Y比例:" (rtos (gxl-dxf ent 42) 2 1))
                                       (strcat "Z比例:" (rtos (gxl-dxf ent 43) 2 1))
                                       (strcat "角度:" (rtos (toang (vla-get-Rotation obj) 1) 2 1) "度")
      ))
      )
      ((= name "LEADER")
      (setq lst (list "【引线】" laynm (strcat "标注样式:" (vla-get-StyleName obj))
                                       (strcat "引线类型:" (gxl-dxf (list (cons 0 "折线") (cons 1 "样条曲线")) (gxl-dxf ent 72)))
      ))
      )
      ((= name "LINE")
      (setq lst (list "【直线】" laynm (strcat "长度:" (rtos (vla-get-length obj) 2 0))
                                       (strcat "角度:" (rtos (toang (vla-get-angle obj) 1) 2 1) "度")
      ))
      )
      ((= name "LWPOLYLINE")
      (setq lst (list "【多段线】" laynm (strcat "常量宽度:" (if (gxl-dxf ent 43) (rtos (vla-get-ConstantWidth obj) 2 0) "变宽度"))
                                          (strcat "多段线:" (if (= (vla-get-Closed obj) :vlax-false) "不闭合" "闭合"))
                                          (strcat "面积:" (rtos (/ (vla-get-Area obj) mjbl) 2 2) "㎡")
      ))
      )
      ((= name "MLINE")
      (setq lst (list "【多线】" laynm (strcat "多线样式:" (vla-get-StyleName obj))
                                       (strcat "比例因子:" (rtos (gxl-dxf ent 40) 2 1))
                                       (strcat "对齐:" (nth (gxl-dxf ent 70) '("上" "零" "下")))
      ))
      )
      ((= name "MTEXT")
      (setq lst (list "【多行文字】" laynm (strcat "高度:" (rtos (vla-get-Height obj) 2 0))
                                             (strcat "角度:" (rtos (toang (vla-get-Rotation obj) 1) 2 1) "度")
                                             (strcat "样式:" (vla-get-StyleName obj))
      ))
      )
      ((or (= name "OLEFRame") (= name "OLE2FRame"))
      (setq lst (list "【OLE边框】" laynm (strcat "格式版本号:" (itoa (gxl-dxf ent 70)))))
      )
      ((= name "POINT")
      (setq lst (list "【点】" laynm))
      )
      ((= name "POLYLINE")
      (setq lst (list "【三维多段线】" laynm))
      )
      ((= name "RAY")
      (setq lst (list "【射线】" laynm))
      )
      ((= name "REGION")
      (setq lst (list "【面域】" laynm (strcat "格式版本号:" (itoa (gxl-dxf ent 70)))))
      )
      ((= name "SHAPE")
      (setq lst (list "【形】" laynm (strcat "高度:" (rtos (vla-get-Height obj) 2 0))
                                       (strcat "宽度系数:" (rtos (vla-get-ScaleFactor obj) 2 1))
                                       (strcat "角度:" (rtos (toang (vla-get-Rotation obj) 1) 2 1) "度")
      ))
      )
      ((= name "SOLID")
      (setq lst (list "【实体】" laynm))
      )
      ((= name "SPLINE")
      (setq lst (list "【样条曲线】" laynm (strcat "多段线:" (if (= (vla-get-Closed obj) :vlax-false) "不闭合" "闭合"))
                                             (strcat "阶数:" (rtos (vla-get-Degree obj) 2 0))
                                             (strcat "面积:" (rtos (/ (vla-get-Area obj) mjbl) 2 2) "㎡")
      ))
      )
      ((= name "TEXT")
      (setq lst (list "【文字】" laynm (strcat "高度:" (rtos (vla-get-Height obj) 2 0))
                                       (strcat "宽度系数:" (rtos (vla-get-ScaleFactor obj) 2 1))
                                       (strcat "角度:" (rtos (toang (vla-get-Rotation obj) 1) 2 1) "度")
                                       (strcat "样式:" (vla-get-StyleName obj))
                                       (strcat "对齐:" (nth (vla-get-Alignment obj) '("Left" "Center" "Right" "Aligned" "Middle" "Fit" "TopLeft" "TopCenter" "TopRight"
                                                                                        "MiddleLeft" "MiddleCenter" "MiddleRight" "BottomLeft" "BottomCenter" "BottomRight")))
      ))
      )
      ((= name "TOLERANCE")
      (setq lst (list "【公差】" laynm (strcat "标注样式:" (vla-get-StyleName obj))
                                       (strcat "文字样式:" (vla-get-TextStyle obj))
                                       (strcat "文字高度:" (rtos (vla-get-TextHeight obj) 2 1))
      ))
      )
      ((= name "TRACE")
      (setq lst (list "【宽线】" laynm))
      )
      ((= name "VERTEX")
      (setq lst (list "【顶点】" laynm (strcat "起始宽度:" (rtos (gxl-dxf ent 40) 2 0))
                                       (strcat "结束宽度:" (rtos (gxl-dxf ent 41) 2 0))
                                       (strcat "凸度:" (rtos (gxl-dxf ent 42) 2 1))
      ))
      )
      ((= name "XLINE")
      (setq lst (list "【构造线】" laynm))
      )
      (T
      (setq lst (list "【未知对象】" laynm))
      )
    )
    (apply 'strcat (mapcar '(lambda (x)(strcat x "\n")) lst))
)
(if (setq ent (nentselp pt)
            ent (if (and ent (= (type (last (last ent))) 'ename))
                  (last (last ent))
                  (car ent)
                )
      )
(dis ent)
   )
)
(defun c:DynInfo(/ loaded openview closeview)
(defun openview(/ arxs)
    (VL-ACAD-DEFUN 'InfoCallBak)
    (if (null mjdw)
      (progn
(INITget 7 "Yes No")
(setq Mjdw (getKword "\n以毫米为单位?[<Yes/No>]<No>:"))
(if (= mjdw "Yes")
   (setq mjdw 1000)
   (setq mjdw 999)
)
      )
    )
    (HFB_PointMonitor)
    (HFB_PointMonitor "InfoCallBak")
    (princ "\n动态信息查看打开!")
    (setq *dynViewEnt* t)
    )
(defun closeview()
    (HFB_PointMonitor)
    (princ "\n动态信息查看关闭!")
    (setq *dynViewEnt* nil)
    )
(cond ((= 16 (atoi (getvar 'acadver)))
(if (not (member "dynarxfor2004-2006.arx" (arx)))
    (if (setq fn (findfile "dynarxfor2004-2006.arx"))
      (setq loaded (arxload fn "1"))
      (setq loaded "2")
      )
    (setq loaded "3") ;_ 已加载
    )
)
((= 17 (atoi (getvar 'acadver)))
(if (not (member "dynarxfor2007-2009.arx" (arx)))
    (if (setq fn (findfile "dynarxfor2007-2009.arx"))
      (setq loaded (arxload fn "1"))
      (setq loaded "2")
      )
    (setq loaded "3")
    )
)
((= 18 (atoi (getvar 'acadver)))
(if (= "x86" (getenv "PROCESSOR_ARCHITECTURE"))
    (if (not (member "dynarxfor2010-2012x32.arx" (arx)))
      (if (setq fn (findfile "dynarxfor2010-2012x32.arx"))
      (setq loaded (arxload fn "1"))
      (setq loaded "2")
      )
      (setq loaded "3")
      )
    (if (not (member "dynarxfor2010-2012x64.arx" (arx)))
      (if (setq fn (findfile "dynarxfor2010-2012x64.arx"))
      (setq loaded
      (arxload (findfile "dynarxfor2010-2012x64.arx")
          "1"))
      (setq loaded "2")
      )
      (setq loaded "3")
      )
    )
)
(t (setq loaded "2"))
)
(if (not (or (= "1" loaded) (= "2" loaded)))
    (if *dynViewEnt*
(closeview)
(openview)
)
    )
(princ)
)

lohas1118 发表于 2011-11-17 09:11:31

支持,很给力

highflybir 发表于 2011-11-16 22:14:07

本帖最后由 highflybir 于 2011-11-18 09:54 编辑

二、让LISP也能JIG,JIG是arx或者.net编程的一个函数,用来在采点过程中与用户交互的一个动态拖拉技术。
JIG的优势在于:可以动态输入,功能齐全,与用户交互性较好,直观方便。

;;;*********************************************************************
;;;SSJIG用法:                                                               
;;;(SSJIG 回调函数 [提示][关键字][控制类型][光标类型][基点][选择集])      
;;;除第一个参数必须外,其他的可以缺省。                                 
;;;---------------------------------------------------------------------
;;;1.回调函数应该为字符串,且代表存在的函数,回调函数只有一个参数,这个
;;;参数为三维点,代表你现在鼠标所在位置.如果回调函数返回一个三维点,将更
;;;改基点位置,如果再附加一个字符串,将更改你的回调函数为字符串代表的函数.
;;;---------------------------------------------------------------------
;;;2.提示--STR 类型,拖动过程中提示的信息。                           
;;;---------------------------------------------------------------------
;;;3.关键字--STR 类型,具体用法可参考initget的关键字说明               
;;;---------------------------------------------------------------------
;;;4.控制类型: --INT 类型                                                
;;;    kGovernedByOrthoMode         = 1,   正交模式是否设置            
;;;    kNullResponseAccepted         = 2,   空回车响应输入请求         
;;;    kDontEchoCancelForCtrlC         = 4,   Ctrl+C不作为取消            
;;;    kDontUpdateLastPoint         = 8,   不更新lastpoint变量         
;;;    kNoDwgLimitsChecking         = 16,    点不作限制,可在图形外      
;;;    kNoZeroResponseAccepted         = 32,    不允许输入零               
;;;    kNoNegativeResponseAccepted = 64,    不允许输入负值            
;;;    kAccept3dCoordinates         = 128,   接受三维坐标点            
;;;    kAcceptMouseUpAsPoint         = 256,   鼠标松开为输入点            
;;;    kAnyBlankTerminatesInput         = 512,   任何空白中断输入            
;;;    kInitialBlankTerminatesInput= 1024,初始空白中断输入            
;;;    kAcceptOtherInputString         = 2048,接受其他字符               
;;;    kGovernedByUCSDetect      = 4096,                              
;;;    kNoZDirectionOrtho          = 8192,                              
;;;    kImpliedFaceForUCSChange    = 16384,                           
;;;    kUseBasePointElevation      = 32768,                           
;;;    kAcqureDist               = 65536, 输入作为距离,相当于getdist
;;;    kAcqureAngle                = 131072,输入作为角度,相当于getangle
;;;---------------------------------------------------------------------
;;;5.光标类型:--INT 类型                                             
;;;    kNoSpecialCursor = -1,      // 普通类型                        
;;;    kCrosshair = 0,             // 全屏十字光标                     
;;;    kRectCursor = 1,            // 矩形                              
;;;    kRubberBand = 2,            // 橡皮筋                           
;;;    kNotRotated = 3,            // 未旋转形状                        
;;;    kTargetBox = 4,             // 选取形状                        
;;;    kRotatedCrosshair = 5,      // 旋转的形状.                     
;;;    kCrosshairNoRotate = 6,   // 强制为未旋转的十字形状.         
;;;    kInvisible = 7,             // 光标不可见.                     
;;;    kEntitySelect = 8,          // 拾取目标形状.                     
;;;    kParallelogram = 9,         // 平行四边形状.                     
;;;    kEntitySelectNoPersp = 10,// 选择框,透视图中不可用.         
;;;    kPkfirstOrGrips = 11,       // 自动选择光标.                     
;;;    kCrosshairDashed = 12       // 虚线的十字光标                  
;;;---------------------------------------------------------------------
;;;6.基点: --LIST 类型,三维点表                                    
;;;    用来动态输入时的基点(第一点)                                 
;;;    如果指定了基点,则表明指定点为第一点,否则读取变量LASTPOINT      
;;;---------------------------------------------------------------------
;;;7.选择集:--ENAME 类型或者 PICKSRT类型,暂时保留                  
;;;    (如果指定了选择集,则对这个选择集更新)                           
;;;---------------------------------------------------------------------
;;;SSJIG函数的返回值,正常情况下返回三维点坐标,如果设置了可接受任意字符
;;;则输入字符结束后返回输入的字符串,如果设置了关键字,而用户输入了关键字
;;;则返回关键字。其他情况则返回整数值,代表意义如下:                  
;;;    kModeless       = -17,                                          
;;;    kNoChange       = -6,                                          
;;;    kCancel         = -4,                                          
;;;    kOther          = -3,                                          
;;;    kNull         = -1,                                          
;;;*********************************************************************


;;;*********************************************************************
;;;JIG测试移动选择集                                                      
;;;*********************************************************************
(defun c:ttt(/ ss pt lst p0 ret i x ret)
(setq *error*_Old *error*)                                                ;保存出错处理函数
(setq *error* *error*_New)                                                ;设置新的出错处理
;;回调函数 for SSJig
(defun CallBack (dynpt)
    (setq i (+ i 10000))
    (setq x (entmakex
            (list
                '(0 . "LINE")
                (cons 420 i)
                (cons 10 (trans pt 1 0))
                (cons 11 dynpt)
            )
            )
    )
    (if x (setq ss (ssadd x ss)))
    (foreach obj lst
      (vla-move obj (vlax-3d-point p0) (vlax-3d-point dynpt))
      ;;(vla-update obj)                                                ;无需用vla-update更新
    )
    (setq p0 dynpt)
    ss
)

(vla-StartUndoMark CurDoc)                                                ;(command ".undo" "be")
(setq vv (ssadd))
(setq ss (ssget))
(setq pt (getpoint "\n基点:"))
(setq p0 (trans pt 1 0))
(setq lst (GetObjects ss))
(setvar "lastPoint" p0)
(setq i 0)

;;|
(setq ret (ssJIG "CallBack"                                                ;回调函数名
                   "\n下一点(the next point): "                              ;提示符
                   "Set Exit"                                                ;关键字
                   (+ 1                                                      ;支持正交模式
                      2                                                      ;允许空回车
                      4                                                      ;Ctrl+C不作为取消
                      16                                                ;不限制点在图形外
                      128                                                ;接受3d坐标
                      2048                                              ;接受任意字符
                      65536                                                 ;输入作为距离131072输入作为角度
                   )
                   2                                                      ;橡皮线效果
                   p0                                                      ;基点
            )
);;|;

;|
(setq ret (HFB_PointMonitor "CallBack" ss))                              ;比较同HFB_PointMonitor函数效果
(setq ret (getpoint pt "\n第二点(2nd point): "))
(HFB_PointMonitor);;|;

;;(setq ret (dyndraw "CallBack" "\n下一点:" "Set" (+ 1 2 4 16 128 2048 8192) 2 p0))      ;Compare to Alexander Rivilis's
;;(setq ret (draggen ss p0"CallBack"0 0 T   "\n下一点(the next point):"))            ;Compare to DragGen mothed
;;(Fsxm-Jig "CallBack" "指定顶点")                                                      ;Compare to FSXM's
(cond
    ( (= (type ret) 'LIST)
      (if (= (type (cdr ret)) 'STR)
      (princ (strcat "\n你选择了关键字(You entered a keyword):" (cdr ret)"\n"))
      (princ (strcat "\n最后返回点坐标是(The last position is): " (vl-princ-to-string ret)))
      )
    )
    ( (= (type ret) 'STR)
      (princ (strcat "\n你输入了字符(You entered a string): " ret "\n"))
    )
    (t
      (princ (strcat "\n其他返回值(Return other value):" (itoa ret) "\n"))
    )
)
(vla-EndUndoMark curdoc)                                                ;(command ".undo" "e")
(gc)
(princ)
)


下面以QJChen的一个双向动态阵列为例子,演示如何将以前用(grread)做的程序稍加修改就变成了JIG了。
在此感谢Qjchen,如有冒犯版权,多加原谅。原帖地址如下:
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=85752




highflybir 发表于 2011-11-16 22:17:21

本帖最后由 highflybir 于 2011-11-18 01:01 编辑

三、DragGen函数让你的拖动大量物体时候更给力。
      XFormSS函数让你的对大量物体进行矩阵变换时快速有效。


;;;*********************************************************************
;;;Draggen用法:                                                         
;;;(DragGen 选择集/图元 [基点] [回调函数] [光标类型] [拖动模式] [执行]
;;;除第一个参数必须外,其他的可以缺省。                                 
;;;选择集/图元,基点和回调函数同SSJIG的用法。                           
;;;光标类型--INT 类型,只有三种,0,十字;1,无;2,选取状                  
;;;拖动模式--INT 类型,0,平移;1,旋转;2,缩放;3镜像;以后再添加            
;;;执行与否--如果此参数空或为nil,仅显示拖动效果,而不实际执行变换      
;;;此函数用以对大量选择集进行拖动等变换效果,尤为明显,快于SSJIG.      
;;;关键字和控制位的设置请在前面加initget,同getpoint之类的函数。      
;;;---------------------------------------------------------------------
;;;回调函数返回值,如果返回点,依据拖动模式对选择集作几何变换.         
;;;如果返回选择集/图元,则对他们作更新。如果返回一个标准的CAD变换矩阵,则
;;;对选择集/图元做指定的矩阵变换。(如错切,镜像,透视等)            
;;;---------------------------------------------------------------------
;;;函数最终返回值为当前点位置和变换的矩阵表。                           
;;;这个函数要求用户对矩阵变换有一定了解。                              
;;;需要特殊说明的是:回调函数传入的点,是一个UCS下的点坐标。            
;;;*********************************************************************

;;;自定义的回调函数 for DragGen
(defun CallBack1 (DynPt)
(redraw)
(grdraw pt dynpt -1)
(trans dynpt 1 0)
)
(vl-acad-defun 'CallBack1)


;;;*********************************************************************
;;;测试Draggen--移动                                                      
;;;*********************************************************************
(defun C:TCC(/ ss p0 ret pt)
(if (and (setq ss (ssget))
         (RedrawSel ss 3)
         (setq pt (getpoint "\n指定基点:"))
      )
    (progn
      (setq p0 (trans pt 1 0))
      (setvar "lastPoint" pt)
      (prompt "\n指定第二个点:")   
      (setq ret (draggen ss p0 "CallBack1" 0 0 T))
      (princ ret)
      (RedrawSel ss 4)
    )
)
(redraw)
(princ)
)

;;;*********************************************************************
;;;测试Draggen--旋转                                                      
;;;*********************************************************************
(defun C:TRR(/ ss p0 ret pt)
(if (and (setq ss (ssget))
         (RedrawSel ss 3)
         (setq pt (getpoint "\n指定基点:"))
      )
    (progn
      (setq p0 (trans pt 1 0))
      (setvar "lastPoint" pt)
      (initget "Copy Reference")
      (prompt "\n指定旋转角度,或 [复制(C)/参照(R)]:")
      (setq ret (draggen ss p0 "CallBack1" 1 0 T))
      (princ ret)
      (RedrawSel ss 4)
    )
)
(redraw)
(gc)
(princ)
)

;;;*********************************************************************
;;;测试Draggen--图元更新                                                
;;;*********************************************************************
(defun C:TGG(/ ss p0 pt lst ret)
;;自定义回调函数for draggen --更新选择集
(defun CallBack (DynPt)
    (redraw)
    (grdraw pt dynpt -1)
    (foreach obj lst
      (vla-move obj (vlax-3d-point p0) (vlax-3d-point (trans dynpt 1 0)))
    )
    (setq p0 (trans dynpt 1 0))
    ss
)

(vla-StartUndoMark curDoc)
;;程序执行部分
(if (and (setq ss (ssget))
         (RedrawSel ss 3)
         (setq pt (getpoint "\n指定基点:"))
      )
    (progn
      (setq p0 (trans pt 1 0))
      (setvar "lastPoint" pt)
      (setq lst (GetObjects ss))
      (setq ret (draggen ss p0 "CallBack" 0 0 T "\n指定第二个点:"))
      (princ ret)
      (RedrawSel ss 4)
    )
)
(vla-EndUndoMark curdoc)
(redraw)
(gc)
(princ)
)

;;;*********************************************************************
;;;测试Draggen--矩阵变换                                                
;;;*********************************************************************
(defun C:TMM(/ ss p0 pt ret)
;;自定义回调函数for draggen --矩阵变换
(defun CallBack (DynPt / vec)
    (redraw)
    (grdraw pt dynpt -1)
    (setq vec (mapcar '- (trans dynpt 1 0) p0))
    (list
      (list 1. 0. 0. (car vec))
      (list 0. 1. 0. (cadr vec))
      (list 0. 0. 1. 0.)
      (list 0. 0. 0. 1.)
    )
)

;;程序执行部分
(if (and (setq ss (ssget))
         (RedrawSel ss 3)
         (setq pt (getpoint "\n指定基点:"))
      )
    (progn
      (setq p0 (trans pt 1 0))
      (setvar "lastPoint" pt)
      (prompt "\n指定第二个点:")
      (setq ret (draggen ss p0 "CallBack" 0 0 T))
      (princ ret)
      (RedrawSel ss 4)
    )
)
(redraw)
(gc)
(princ)
)

;;;*********************************************************************
;;;测试XForm                                                               
;;;此函数用来对大量选择集的变换。因为vla-transformby,vla-move,vla-rotate
;;;对这样的需求在速度上不能满足要求时,需要用一个arx来高效地执行。      
;;;另外,也用于command命令不能使用的场合。                              
;;;经测试速度,对大量图元的变换,用此能提高速度20倍,甚至更多。         
;;;用法:(Xfrom Selection Matrix_List)                                 
;;;            Selection   ------非空选择集      PICKSET            
;;;            Matrix_List ------变换矩阵表(4X4)   LIST               
;;;两个参数不能缺省,变换矩阵为标准的CAD等比矩阵.                     
;;;返回T代表成功变换,nil变换失败,此时请检测选择集中是否有被锁定的图元,
;;;或者变换矩阵为标准的CAD矩阵,为统一比例变换的矩阵。                  
;;;*********************************************************************
(defun C:TXX (/ sel pt1 pt2 vec)
(if (and (setq sel (ssget))
         (setq pt1 (getpoint "\n基点:"))
         (setq pt2 (getpoint "\n目标点:"))
      )
    (progn
      (redraw)
      (setq vec (mapcar '- pt2 pt1))
      (setq vec (trans vec 1 0 T))
      (grdraw pt1 pt2 1)
      (XformSS sel
            (list
            (list 1. 0. 0. (car vec))
            (list 0. 1. 0. (cadr vec))
            (list 0. 0. 1. 0.)
            (list 0. 0. 0. 1.)
            )
      )
    )
)
)

1548845899 发表于 2011-11-16 22:39:09

qjchen 发表于 2011-11-16 22:51:45

敬仰不止
以前我都只能是用外国人的程序实现,现在高飞鸟兄带来更好的程序
谢谢~

chpmould 发表于 2011-11-16 22:54:08

支持,很给力,对LISP来说是一种弥补.

sen.sam 发表于 2011-11-16 23:20:33

感觉grread函数外国人用得出神入化,有了版主的函数,我们也可以做出出神入化的动态效果

carrot1983 发表于 2011-11-17 09:16:20

非常强悍,一直想学习C#就是为了解决两大难题:
1. grread函数的局限。
2. DCL无法实现非模态。

谢谢高飞鸟
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 【飞鸟集】心随我动--为LISP定制的动态输入,拖拉和动态信息函数(更新至20130731)