牢固 发表于 2013-9-24 15:33:16

【Gu_xl】动态复制、移动(可缩放、旋转、镜像、对齐等)

本帖最后由 牢固 于 2013-9-24 15:36 编辑

功能:选择对象进行复制或移动。复制或移动过程中可以对源对象进行缩放、旋转、镜像、对齐等动作。
源码中大量使用了矩阵运算(使用了高飞鸟的矩阵运算函数库)和动态GRREAD(自定义的带捕捉的GRREAD函数)。
程序为开源代码,程序中可能有Bug,也可能不符合您平时画图习惯,请大家不要发帖求我改进或改编成符合您的绘图方式的程序,该源码仅作为大家学习交流的代码,大家尽可以拿去研习,可以提出改进意见,然后自己改编成合适自己绘图的方式的程序,或进一步改进优化,如大家能将自己改进的代码发上来共享,本人将不胜感激,一律给予适当加分!
主程序代码:
;;;*************************************************
(princ "\n**动态复制、移动 By Gu_xl 命令: DynDrag**")
;;动态复制、移动(c:DynDrag)
(defun c:DynDrag (/ SS       ORIGN    LOOP   COPYFLAG BASEPT
                  AXORIGNAXBASEPT SOURCEOBJS      TARGETOBJS
                  TMP      GR       PT       TMAT   NEWORIGN
                  ROT      P1       P2       SCALE    P3
                  P4 TARGETDIS REFDIS LASTOBJS LASTBASEPT
                  KD MOVEFLAG    TMPBASEPT
                  )
(princ "\n选择物体:")
(if (and
      (setq ss (ssget))
      (progn
          (initget 6)
      (setq orign (getpoint "\n选择基点:"))
          )
      (setq Loop t)
      )
    (progn
      (initget "C M")
      (setq copyflag (getkword "\n[复制<C>/移动<M>]<C>:"))
      (setq copyflag (or (not copyflag) (= "C" copyflag)))
      (setq basept (trans orign 1 0))
      (setq SourceObjs
             (gxl-SEL-MAPCAR
               ss
               '(lambda (x) (vlax-ename->vla-object x))
               )
            )
      (if CopyFlag
          (setq targetObjs (mapcar 'vla-copy SourceObjs))
      (progn
          (setq targetObjs SourceObjs)
          (setq SourceObjs (mapcar 'vla-copy SourceObjs))
          )
      )
      (setq ss (ssadd)
            MoveFlag t)
      (foreach obj targetObjs (ssadd (vlax-vla-object->ename obj) ss))
      ;(setq lastobjs SourceObjs lastbasept basept)
      (prompt "\r**点取位置或 {改基点/改转角/转90度/镜像/左右翻/上下翻/缩放/对齐/}<退出>:")
      (while loop
      (setq gr (gxl-GE-GRREAD '(t 15) orign ss))
      (princ "\r**点取位置或 {改基点/改转角/转90度/镜像/左右翻/上下翻/缩放/对齐/}<退出>:")
      (cond
          ((and MoveFlag (= 5 (car gr))) ;_ 复制移动
         (grdraw orign (cadr gr) 7 1)
         (setq pt (trans (cadr gr) 1 0))
         (if (> (distance pt basept) (* 0.005 (getvar "viewsize")))
             (progn
         (setq tmat (vlax-tmatrix (gxl-Mat-TranslateBy2P basept pt)))
         (mapcar '(lambda (x)(vla-TransformBy x tmat)) targetObjs)
         (setq basept pt)
         (mapcar '(lambda (x) (vla-Highlight x :vlax-true)) targetObjs)
         )
             )
         )
          ((and MoveFlag (= 3 (car gr))) ;_ 确定
         (grdraw orign (cadr gr) 7 1)
         (setq pt (trans (cadr gr) 1 0))
         (setq tmat (vlax-tmatrix (gxl-Mat-TranslateBy2P basept pt)))
         (mapcar '(lambda (x)(vla-TransformBy x tmat)) targetObjs)
         (setq lastObjs targetObjs lastbasept basept)
         (if copyflag
             (progn               
               (setq targetObjs (mapcar 'vla-copy targetObjs))
               (setq ss (ssadd))
               (foreach obj targetObjs
               (ssadd (vlax-vla-object->ename obj) ss)
               )
               
               )
             (progn
               (setq MoveFlag nil)
               (mapcar 'vla-delete SourceObjs)
               )
             )
            
         )
          ((or (= 25 (car gr)) ;_ 退出
               (and (= 2 (car gr)) (or (= (cadr gr) 13) (= (cadr gr) 32)))
               )
         (redraw)
         (if copyFlag
             (progn
         (mapcar 'vla-delete targetObjs)
         )
             )
         (setq loop nil)
         )
          ((and (= 2 (car gr))
                (or (= (cadr gr) (ascii "t")) (= (cadr gr) (ascii "T")))
                ) ;_ 改基点
         (redraw)
         
         (if (and
               (not copyflag)
               lastobjs
               )
             (progn
               (initget 6)
         (while (not (setq Neworign (getpoint "\n选择基点:"))))
         (setq Neworign (trans Neworign 1 0))
               (setq tmat (vlax-tmatrix (gxl-Mat-TranslateBy2Pbasept Neworign)))
               (mapcar '(lambda (x)(vla-TransformBy x tmat)) lastobjs)
               (setq basept Neworign)
               )
             (if (and copyflag lastobjs)
               (progn
               (mapcar '(lambda (x) (vla-put-Visible x :vlax-false)) targetObjs)
               (initget 6)
               (while (not (setq Neworign (getpoint "\n选择基点:"))))
               (setq Neworign (trans Neworign 1 0))
               (setq tmat (vlax-tmatrix (gxl-Mat-TranslateBy2P lastbasept Neworign)))
               (mapcar '(lambda (x)(vla-TransformBy x tmat)) lastobjs)
               (mapcar '(lambda (x) (vla-put-Visible x :vlax-true)) targetObjs)
               )
               (progn
               (while (not (setq basept (getpoint "\n选择基点:"))))
               (setq basept (trans basept 1 0))
               )
               )
             )
         
         )
          ((and (= 2 (car gr))
                (or (= (cadr gr) (ascii "r")) (= (cadr gr) (ascii "R")))
                ) ;_ 改转角
         (setq tmp targetObjs tmpbasept basept)
         (if copyflag
             (progn
         (mapcar '(lambda (x) (vla-put-Visible x :vlax-false)) tmp)
         (setq targetObjs lastObjs basept lastbasept)
         (setq ss (ssadd))
         (foreach obj targetObjs
               (ssadd (vlax-vla-object->ename obj) ss)
               )
         )
             )
         (command "_rotate" ss "" (trans basept 0 1))
         (while (= 1 (logand (getvar 'cmdactive) 1))
             (command pause)
             )
         (if copyflag
             (progn
         (mapcar '(lambda (x) (vla-put-Visible x :vlax-true)) tmp)
         (setq targetObjs tmp basept tmpbasept)
         (setq ss (ssadd))
         (foreach obj targetObjs
               (ssadd (vlax-vla-object->ename obj) ss)
               )
         )
             )
         )
          ((andMoveFlag
               (= 2 (car gr))
                (or (= (cadr gr) (ascii "a")) (= (cadr gr) (ascii "A")))
                ) ;_ 转90度
         (setq tmat (vlax-tmatrix (gxl-Mat-Rotation basept pi2)))
         (mapcar '(lambda (x)(vla-TransformBy x tmat)) targetObjs)
         )
          ((and MoveFlag
                (= 2 (car gr))
                (or (= (cadr gr) (ascii "m")) (= (cadr gr) (ascii "M")))
                ) ;_ 镜像
         (initget 7)
         (setq p1 (getpoint "\n指定第一点:"))
         (initget 7)
         (setq p2 (getpoint p1 "\n指定第二点:"))
         (setq tmat (gxl-Mat-Reflect p1 p2))
         (setq basept (gxl-MAT-MXP tmat basept)
               tmat (vlax-tmatrix tmat)
               )
         (mapcar '(lambda (x)(vla-TransformBy x tmat)) targetObjs)
         )
          ((and MoveFlag
                (= 2 (car gr))
                (or (= (cadr gr) (ascii "s")) (= (cadr gr) (ascii "S")))
                ) ;_ 左右翻
         (setq tmat (vlax-tmatrix (gxl-Mat-Reflect basept (polar basept pi2 10))))
         (mapcar '(lambda (x)(vla-TransformBy x tmat)) targetObjs)
         )
          ((and MoveFlag
                (= 2 (car gr))
                (or (= (cadr gr) (ascii "d")) (= (cadr gr) (ascii "D")))
                ) ;_ 上下翻
         (setq tmat (vlax-tmatrix (gxl-Mat-Reflect basept (polar basept 0 10))))
         (mapcar '(lambda (x)(vla-TransformBy x tmat)) targetObjs)
         )
          ((and MoveFlag
                (= 2 (car gr))
                (or (= (cadr gr) (ascii "l")) (= (cadr gr) (ascii "L")))
                ) ;_ 缩放
         (command "_scale" ss "" )
         (while (= 1 (logand (getvar 'cmdactive) 1))
             (command pause)
             )
         ;|(initget 7 "R")
         (setq scale (getdist (trans basept 0 1) "\n指定比例因子或 [参照(R)]:"))
         (if (= scale "R")
             (progn
               (initget 6)
               (setq refdis (getdist (trans basept 0 1) "\n指定参照长度 <1>:"))
               (if (null refdis)(setq refdis 1.0))
               (initget 7)
               (setq targetdis (getdist"\n指定目标长度::"))
               (setq scale (/ targetdis refdis))
            )
             )
         (setq tmat (vlax-tmatrix (gxl-Mat-Scalebase basept scale)))
         (mapcar '(lambda (x)(vla-TransformBy x tmat)) targetObjs)|;
         )
          ((and MoveFlag
                (= 2 (car gr))
                (or (= (cadr gr) (ascii "f")) (= (cadr gr) (ascii "F")))
                ) ;_ 对齐
         (initget 7)
         (setq p1 (getpoint "\n指定源对象第1点:"))
         (initget 7)
         (setq p3 (getpoint p1 "\n指定目标第1点:"))
         (grdraw p1 p3 1 -1)
         (initget 7)
         (setq p2 (getpoint "\n指定源对象第2点:"))
         (initget 7)
         (setq p4 (getpoint "\n指定目标第2点:"))
         (grdraw p2 p4 1 -1)
         (setq p1 (trans p1 1 0))
         (setq p2 (trans p2 1 0))
         (setq p3 (trans p3 1 0))
         (setq p4 (trans p4 1 0))
         (setq scale (/ (distance p3 p4) (distance p1 p2)))
         (setq tmat (gxl-Mat-TranslateBy2P p1 p3)
               tmat (gxl-MAT-MXM
                        tmat
                        (gxl-Mat-Rotation p1 (- (angle p3 p4) (angle p1 p2)))
                        )
               )
         (initget "Y N")
         (setq kd (getkword "是否基于对齐点缩放对象?[是(Y)/否(N)] <否>:"))
         (setq kd (= "Y" kd))
         (if kd
             (setq tmat
                  (gxl-MAT-MXM
                      (gxl-Mat-Scalebase p3 scale)
                      tmat
                      )
                   )
             )
         (if copyflag
             (progn
               (setq tmp (mapcar 'vla-copy targetObjs))
               (setq lastobjs tmp lastbasept (gxl-MAT-MXP tmat basept))
               (setq tmat (vlax-tmatrix tmat))
               (mapcar '(lambda (x)(vla-TransformBy x tmat)) tmp)
               )
             (progn
               (setq lastobjstargetObjs basept (gxl-MAT-MXP tmat basept))
               (mapcar '(lambda (x)(vla-TransformBy x (vlax-tmatrix tmat))) targetObjs)
               (mapcar 'vla-delete SourceObjs)
               
               (setq MoveFlag nil)
               )
             )
               
         )
          )
      )
      )
    )
(redraw)
(princ)
)
(princ)
全部源码下载:

yzr2002626 发表于 2013-9-24 18:10:11

顶G版,太给力了

newer 发表于 2013-9-24 18:18:12

学习下,顶固版。

yoyoho 发表于 2013-9-24 18:37:47

感谢G版分享程序,下载学习了!

HLCAD 发表于 2013-9-24 20:09:58

牢固大侠的程序一定要支持!

HLCAD 发表于 2013-9-24 20:10:30

本帖最后由 HLCAD 于 2013-9-25 16:35 编辑

发现一个小BUG:命令:
命令: DynDrag

选择物体:
选择对象: 指定对角点: 找到 27 个

选择对象:

选择基点:
[复制<C>/移动<M>]<C>:
**点取位置或 {改基点/改转角/转90度/镜像/左右翻/上下翻/缩放/对齐/}<退出>:_rotate
UCS 当前的正角方向:ANGDIR=逆时针ANGBASE=0.0

选择对象:   找到 0 个
选择对象:
命令: ; 错误: 参数类型错误: 二维/三维点: nil


如果在“[复制<C>/移动<M>]<C>:”这步,在一新位置复制所选实体,再按“R”改转角,则不出错。

A82613035571210 发表于 2013-9-25 07:22:00


頂G版,太給力了

守仁格竹GM 发表于 2013-9-25 08:06:55

学习下 顶一个

xingwan2013 发表于 2013-9-25 10:20:13

感谢G版分享程序!

sicky111 发表于 2013-9-25 20:37:36

G版给力哦。

lingduwx 发表于 2013-9-28 13:45:50

顶一下,这个强大

dbx5511 发表于 2013-10-1 18:32:08

本帖最后由 dbx5511 于 2013-10-2 15:09 编辑

这个是非常的不错,稍微有一点小小的瑕疵,就是命令执行的最后一个拷贝的东西,旋转后,会产生一个所拷贝的物体,实际上这个物体是需要的,就是命令最后要终止的时候,动态预览的那个选择集,会落在图上,会产生一组所选来拷贝或者旋转的物体,虚线显示,需要人工取删除。其他的非常好,比天正建筑的自由拷贝还要好。另外一个就是最好拷贝一次后,如果有调整角度(旋转),下一个的动态预览的角度最好是调整后的,现在的预览角度是最初开始拷贝的角度。

bai2000 发表于 2013-10-6 18:40:55

12楼的问题是个问题

dbx5511 发表于 2013-10-6 20:07:12

最近还在用这个插件,感觉如果能在拷贝和旋转中间切换,就更好了,另外一个问题就是如果图纸文件很大的话,有捕捉的时候,操作命令会很卡。

721118231 发表于 2013-10-10 17:46:37

下来学习一下
页: [1] 2 3
查看完整版本: 【Gu_xl】动态复制、移动(可缩放、旋转、镜像、对齐等)