明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 6491|回复: 44

[源码] 发个小程序,设置两点,快速同步【模型·双视口】~~~【20211227尝试修复BUG】

  [复制链接]
发表于 2021-6-26 22:43:14 | 显示全部楼层 |阅读模式
本帖最后由 masterlong 于 2021-12-27 18:58 编辑

程序在编制时有疏漏
现尝试修复BUG
因为没有时间测试
暂将修复后的lisp放在35楼
供有兴趣的同学试用
若反映没有问题了再放到顶楼

;;-----------------------------------------------------------------------------------以下代码有bug,见上说明

绘图或者校审过程
经常需要利用双视口
来对照两个平面的同一个区域

;;QG```````模型中直接指定两个点,记录相对坐标后再切分为双视口
;;GG```````根据相对坐标,“同步”两个视口


;;GG```````根据相对坐标,“同步”两个视口
(defun c:gg()
(princ "\nQG```模型中指定两点,记录相对坐标后切分为双视口\nGG```根据相对坐标,“同步”两个视口")
(setq *acad* (vlax-get-acad-object))

(if (null gg#viewlist)
  (c:qg)
  (if (= (strcase (getvar "ctab")) "MODEL")
   (if (= 2 (length (vports)))
    (progn
     (command "undo" "g")
     (setq 0cvid  (getvar "cvport"))
     (setq 0cvctr   (u2w (getvar "viewctr")))
     (setq 0cvsize  (getvar "viewsize"))
     
     (setq ggbiao (cdr (assoc 0cvid gg#viewlist)))
     (setq 9pt (vlax-3d-point (w2u (mapcar '+ 0cvctr (cadr ggbiao)))))
     (setvar "cvport" (car ggbiao))
        
        ;;【下面代码3选1】
        ;;(vla-ZoomCenter *acad* 9pt (caddr ggbiao))       ;;按记录默认值显示视窗高度
        ;;(vla-ZoomCenter *acad* 9pt (* 0cvsize (cadddr ggbiao)))  ;;按相对比例显示视窗高度
        (vla-ZoomCenter *acad* 9pt 0cvsize)          ;;按第1视口高度设置第2视口高度(手感比较好)
     
     (setvar "cvport" 0cvid)
     (princ "\n已根据记录“同步”两个视口")
     (command "undo" "e")
    )
    (princ "\n本命令用于在【模型·双视口】时,按相对位置快速同步两个视口。\n模型空间非双视口,不能执行本命令")
   )
   (princ "\n本命令用于在【模型·双视口】时,按相对位置快速同步两个视口。\n当前空间非模型,不能执行本命令")
  )
)
(princ)
)

;;QG```````模型中直接指定两个点,记录相对坐标后再切分为双视口
(defun c:qg()
(princ "\nQG```模型中指定两点,记录相对坐标后切分为双视口\nGG```根据相对坐标,“同步”两个视口")
(setq *acad* (vlax-get-acad-object))

(if (= (strcase (getvar "ctab")) "MODEL")
  (if (and
     (setq 0pt (getpoint "\n指定第1视口的中心点 : "))
     (setq 1pt (getpoint 0pt "\n指定第2视口的中心点 : "))
   )
   (progn
     (setq 9cvsize  (getvar "viewsize"))
     (cond
      ((< 2 (length (vports))) (command "-vports" "si" "-vports" "2" "v"))
      ((= 1 (length (vports))) (command "-vports" "2" "v"))
     )
     (setq 0cvid (getvar "cvport"))
     (vla-ZoomCenter *acad* (vlax-3d-point 0pt) 9cvsize)
     (setvar "cvport" (car (car (reverse (vports)))))
     (vla-ZoomCenter *acad* (vlax-3d-point 1pt) 9cvsize)
     (setvar "cvport" 0cvid)
     (gq_save)
   )
   (princ "未指定两点。程序退出")
  )
  (progn
   (princ "\n当前空间为布局,本命令只能用于模型,现在切换至模型")
   (setvar "ctab" "model")
   (c:qg)
  )
)
(princ)
)
(defun gq_save()
  ;;(princ "符合【模型·双视口】条件")
  (setq 0cvid  (getvar "cvport"))    ;;获取当前模型视口的id````模型双视口时,这个值一般为2或3
  (setq 0cvctr   (u2w (getvar "viewctr")))  ;;获取当前模型视口的中心坐标,转换为世界坐标系
  (setq 0cvsize  (getvar "viewsize"))    ;;获取当前模型视口的高
  (setvar "cvport" (car (car (reverse (vports))))) ;;切换至另一个视口
  (setq 1cvid  (getvar "cvport"))    ;;获取第2视口的id
  (setq 1cvctr   (u2w (getvar "viewctr")))  ;;获取第2视口的中心坐标,转换为世界坐标系
  (setq 1cvsize  (getvar "viewsize"))    ;;获取第2视口的高
  (setq 01dist (mapcar '- 1cvctr 0cvctr))  ;;计算0~1视口中心相对坐标
  (setq 10dist (mapcar '- 0cvctr 1cvctr))  ;;计算1~0视口中心相对坐标
  ;;按规则记录`````````````````第4、5个参数备用(根据实际使用手感决定如何调整视窗大小)
  (setq gg#viewlist
    (list
      (list 0cvid 1cvid 01dist 1cvsize (/ 0cvsize 1cvsize 1.0))
      (list 1cvid 0cvid 10dist 0cvsize (/ 1cvsize 0cvsize 1.0))
    )
  )
     ;;设置所有打开文件共享此列表
     ;;(vl-propagate 'gg#viewlist)
  
  (setvar "cvport" 0cvid)        ;;恢复原始视口
  (princ "\n相对坐标已记录。此后可使用【gg】命令快速“同步”")
(princ)
)

;999坐标WCS=>UCS
(defun w2u( pt )
(trans pt 0 1)
)

;999坐标UCS=>WCS
(defun u2w( pt )
(trans pt 1 0)
)

评分

参与人数 4明经币 +4 金钱 +5 收起 理由
hhhlike + 1 + 5 挺好用的
panliang9 + 1 多年以前一直想要的东西。
tigcat + 1 很给力!我感觉这个非常有用
start4444 + 1 很给力!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2021-6-28 11:08:44 | 显示全部楼层
是不是可以增加反应器,达到不需要输入命令自动同步的效果
回复 支持 1 反对 1

使用道具 举报

 楼主| 发表于 2021-12-27 18:52:10 | 显示全部楼层
本帖最后由 masterlong 于 2022-1-4 11:44 编辑

尝试修复BUG
不过没时间测试
先放这里供有兴趣的同学试用
若没有问题
再更新到顶楼

附件传不上来
代码格式又不玩不溜 ------ IE的问题?用google chrome就可以了
就这样吧


  1. ;;QG```````模型中指定两点,记录相对坐标后切分为左右双视口````根据两点位置关系自动对应视口
  2. ;;GG```````根据相对坐标,“同步”两个视口
  3. ;;CCV``````提取以上相对坐标为基点终点,选择对象既完成视口间复制````自动以当前视口向另一视口进行复制


  4. ;|
  5. 【关于CCV】
  6. 这个程序后期我可能会再做一些调整
  7. 若当前模型非“左右均分双视口”时
  8. 执行CCV仅将模型设为“左右均分双视口”
  9. 也就是相当于GG命令的功能
  10. 再调用CCV时才允许选择图元执行双向复制
  11. 这样应该不容易出现误操作
  12. |;

  13. ;000`````````GG```````根据相对坐标,“同步”两个视口
  14. (defun c:gg()
  15. (c:gg_main)
  16. )
  17. (defun c:gg_main()
  18. (princ "\nQG```模型中指定两点,记录相对坐标后切分为双视口\nGG```根据相对坐标,“同步”两个视口")
  19. (setq *acad* (vlax-get-acad-object))

  20. (if (null gg#viewlist)
  21.   (c:qg)
  22.   (if (= (strcase (getvar "ctab")) "MODEL")
  23.    ;;改为只要是模型,一律改为左右均分双视口。不管原来是单独视口还是多视口,或者双视口(双视口也可能是上下或不等分视口)
  24.    (progn
  25.     (command "undo" "g")
  26.      
  27.     ;;(set2vp_lr)  ;;设定模型为左右均分双视口
  28.     (if (= 2 (length (vports)))
  29.      (progn
  30.       (setq afw (cdr (car (vports))))
  31.       (if (not (or (equal afw '((0.0 0.0) (0.5 1.0))) (equal afw '((0.5 0.0) (1.0 1.0)))))
  32.        (command "-vports" "si" "-vports" "2" "v")
  33.       )
  34.      )
  35.      (command "-vports" "si" "-vports" "2" "v")
  36.     )
  37.    
  38.     ;;根据(vports)特征值,判断当前视口在左还是右
  39.     (setq 999cvid (getvar "cvport"))
  40.     (setq 999vdat (cdr (assoc 999cvid (vports))))
  41.     (setq 999jjj  (apply '+ (car 999vdat)))
  42.     ;;当前为右视口时,ggbiao = gg#viewlist;当前为左视口时,ggbiao = (mapcar '- gg#viewlist)
  43.     (if (= 999jjj 0)
  44.      (setq ggbiao gg#viewlist)
  45.      (setq ggbiao (mapcar '- gg#viewlist))
  46.     )
  47.       
  48.     (setq 0cvid  (getvar "cvport"))
  49.     (setq 0cvctr   (u2w (getvar "viewctr")))
  50.     (setq 0cvsize  (getvar "viewsize"))
  51.     (setq 9pt (vlax-3d-point (w2u (mapcar '+ 0cvctr ggbiao))))
  52.     (setvar "cvport" (car (car (reverse (vports)))))
  53.     (vla-ZoomCenter *acad* 9pt 0cvsize)
  54.     (princ "\n已根据记录“同步”两个视口")
  55.      
  56.     (command "undo" "e")
  57.    )
  58.    (princ "\n本命令用于在【模型·双视口】时,按相对位置快速同步两个视口。\n当前空间非模型,不能执行本命令")
  59.   )
  60. )
  61. (princ)
  62. )

  63. ;000`````````QG```````模型中指定两点,记录相对坐标后切分为左右双视口````根据两点位置关系自动对应视口
  64. (defun c:QG()
  65. (c:QG_main)
  66. )
  67. (defun c:QG_main()
  68. (princ "\nQG```模型中指定两点,记录相对坐标后切分为左右双视口\nGG```根据相对坐标,“同步”两个视口")
  69. (setq *acad* (vlax-get-acad-object))
  70.          
  71. ;;此代码提至前面————加强程序体验:指定点时,可能视窗面积较大
  72. (setq 9cvsize  (getvar "viewsize"))
  73. (if (= (strcase (getvar "ctab")) "MODEL")
  74.   (if (and
  75.      (setq apt (getpoint "\n指定第1视口的中心点 : "))
  76.      (setvar "orthomode" 1)
  77.      (setq bpt (getpoint apt "\n指定第2视口的中心点 : "))
  78.    )
  79.    (progn
  80.      ;;根据两点坐标比较,确定0pt(始终左视口)1pt(始终右视口)
  81.      (setq apt (u2w apt)
  82.        bpt (u2w bpt)
  83.      )   
  84.      (if (= (car apt) (car bpt))
  85.       (if (> (cadr apt) (cadr bpt))
  86.        (setq 0pt apt   1pt bpt)
  87.        (setq 0pt bpt   1pt apt)
  88.       )
  89.       (if (< (car apt) (car bpt))
  90.        (setq 0pt apt   1pt bpt)
  91.        (setq 0pt bpt   1pt apt)
  92.       )
  93.      )
  94.      
  95.      ;;(set2vp_lr)  ;;设定模型为左右均分双视口
  96.      (if (= 2 (length (vports)))
  97.       (progn
  98.        (setq afw (cdr (car (vports))))
  99.        (if (not (or (equal afw '((0.0 0.0) (0.5 1.0))) (equal afw '((0.5 0.0) (1.0 1.0)))))
  100.         (command "-vports" "si" "-vports" "2" "v")
  101.        )
  102.       )
  103.       (command "-vports" "si" "-vports" "2" "v")
  104.      )
  105.      
  106.      ;;根据(vports)特征值,判断当前视口在左还是右
  107.      (setq 999cvid (getvar "cvport"))
  108.      (setq 999vdat (cdr (assoc 999cvid (vports))))
  109.      (setq 999jjj  (apply '+ (car 999vdat)))
  110.      ;;当前为左视口时,切换到右视口
  111.      (if (/= 999jjj 0)
  112.       (setvar "cvport" (car (car (reverse (vports)))))
  113.      )
  114.      
  115.      ;;左右视口分别按0pt、1pt缩放窗口
  116.      (vla-ZoomCenter *acad* (vlax-3d-point 0pt) 9cvsize)
  117.      (setvar "cvport" (car (car (reverse (vports)))))
  118.      (vla-ZoomCenter *acad* (vlax-3d-point 1pt) 9cvsize)
  119.      (gq_save)
  120.    )
  121.    (princ "未指定两点。程序退出")
  122.   )
  123.   (progn
  124.    (princ "\n当前空间为布局,本命令只能用于模型,现在切换至模型")
  125.    (setvar "ctab" "model")
  126.    (c:qg)
  127.   )
  128. )
  129. (princ)
  130. )
  131. (defun gq_save()
  132. (setq gg#viewlist (mapcar '- 1pt 0pt))

  133.      ;;可屏蔽代码`````设置所有打开文档共享此列表
  134.      (vl-propagate 'gg#viewlist)
  135. )

  136. ;000`````````CCV``````提取以上相对坐标为基点终点,选择对象既完成视口间复制````自动以当前视口向另一视口进行复制
  137. (defun c:ccv()
  138. (c:ccv_main)
  139. )
  140. (defun c:ccv_main()
  141. (princ "\nccv```视口同步复制————————两个视口“同步”以后,以相对坐标进行复制")
  142. (setq *acad* (vlax-get-acad-object))

  143. (if (null gg#viewlist)
  144.   (progn
  145.    (princ "\n要使用本命令,必须首先指定双视口的相对坐标")
  146.    (c:qg)
  147.   )
  148.   (progn
  149.    (command "undo" "g")
  150.    
  151.    ;;(set2vp_lr)  ;;设定模型为左右均分双视口
  152.    (if (= 2 (length (vports)))
  153.     (progn
  154.      (setq afw (cdr (car (vports))))
  155.      (if (not (or (equal afw '((0.0 0.0) (0.5 1.0))) (equal afw '((0.5 0.0) (1.0 1.0)))))
  156.       (command "-vports" "si" "-vports" "2" "v")
  157.      )
  158.     )
  159.     (command "-vports" "si" "-vports" "2" "v")
  160.    )
  161.    (if (setq ss (ssget))
  162.     (progn
  163.      ;;根据(vports)特征值,判断当前视口在左还是右
  164.      (setq 999cvid (getvar "cvport"))
  165.      (setq 999vdat (cdr (assoc 999cvid (vports))))
  166.      (setq 999jjj  (apply '+ (car 999vdat)))
  167.      ;;当前为右视口时,ggbiao = gg#viewlist;当前为左视口时,ggbiao = (mapcar '- gg#viewlist)
  168.      (if (= 999jjj 0)
  169.       (setq ggbiao gg#viewlist)
  170.       (setq ggbiao (mapcar '- gg#viewlist))
  171.      )
  172.      
  173.      (setq ent (entlast))
  174.      (command "copy" ss "" "non" '(0 0)  "non" ggbiao)
  175.      (princ "\n预设点快速复制已完成")
  176.      (setq newss (entbackss ent))
  177.      
  178.        ;;以下为个人使用习惯,可屏蔽-----复制后对象形成“上一选择集”
  179.        (oldss2act newss)
  180.        ;;以下代码可屏蔽,将取消复制以后视口“同步”的效果
  181.        (progn
  182.         (setq 0cvid  (getvar "cvport"))
  183.         (setq 0cvctr   (u2w (getvar "viewctr")))
  184.         (setq 0cvsize  (getvar "viewsize"))
  185.         (setq 9pt (vlax-3d-point (w2u (mapcar '+ 0cvctr ggbiao))))
  186.         (setvar "cvport" (car (car (reverse (vports)))))
  187.         (vla-ZoomCenter *acad* 9pt 0cvsize)
  188.        )
  189.        ;;以下代码可屏蔽,将取消选择集复制后的亮显
  190.        (ssdraw ss 3)
  191.        (ssdraw newss 3)
  192.      
  193.      (setvar "cvport" 999cvid)
  194.     )
  195.    )
  196.      
  197.    (command "undo" "e")
  198.   )
  199. )
  200. (princ)
  201. )









  202. ;999公共函数
  203. ;;坐标WCS=>UCS
  204. (defun w2u( pt )
  205. (trans pt 0 1)
  206. )
  207. ;999公共函数
  208. ;;坐标UCS=>WCS
  209. (defun u2w( pt )
  210. (trans pt 1 0)
  211. )
  212. ;999公共函数
  213. ;;一个已存在的选择集,设置成当前选择集
  214. (defun oldss2act( oldss )
  215. (sssetfirst Nil oldss)  ;;将选择集设为夹点显示模式
  216. (ssget "i")
  217. (sssetfirst nil nil)  
  218. )
  219. ;999公共函数
  220. ;;按指定的模式重画一个选择集的全部物体<改模式时,需要先反绘。1-2 3-4.(1->4=1->2->4)>    【支持模型多视口,支持布局中视口】
  221. ;;  1:显示  2:消隐  3:高亮  4:低亮
  222. (defun ssdraw( ss mode / i ent )
  223. (if (= (strcase (getvar "ctab")) "MODEL")
  224.   (if (member mode '(1 2 3 4))
  225.    (foreach vp (reverse (vports))
  226.     (setvar "cvport" (car vp))
  227.     (cond
  228.      ((= (type ss) 'PICKSET)
  229.       (foreach ent (ss2list ss)
  230.        (redraw ent mode)
  231.       )
  232.      )
  233.      ((= (type ss) 'list)
  234.       (foreach ent ss
  235.        (redraw ent mode)
  236.       )
  237.      )
  238.      ((= (type ss) 'ename)
  239.       (redraw ss mode)
  240.      )
  241.     )
  242.    )
  243.   )
  244.   (cond
  245.    ((= (type ss) 'PICKSET)
  246.     (foreach ent (ss2list ss)
  247.      (redraw ent mode)
  248.     )
  249.    )
  250.    ((= (type ss) 'list)
  251.     (foreach ent ss
  252.      (redraw ent mode)
  253.     )
  254.    )
  255.    ((= (type ss) 'ename)
  256.     (redraw ss mode)
  257.    )
  258.   )
  259. )
  260. (princ)
  261. )
  262. ;999```公共函数
  263. ;;获取在图元 ent 之后产生的图元的选择集 ,ent不存在时返回nil
  264. (defun entbackss ( ent / backss)
  265. (if (and ent (vlax-Ename->Vla-Object ent))
  266.   (progn
  267.    (setq backss (ssadd))
  268.    (while (setq ent (entnext ent))
  269.     (if (not (member (cdr (assoc 0 (entget ent))) '("ATTRIB" "VERTEX" "SEQEND")))
  270.      (setq backss (ssadd ent backss))
  271.     )
  272.    )
  273.    (if (zerop (sslength backss))
  274.     (setq backss NIL)
  275.    )
  276.    backss
  277.   )
  278. )
  279. )






 楼主| 发表于 2021-6-27 18:11:05 | 显示全部楼层
本帖最后由 masterlong 于 2021-12-27 19:13 编辑

简单说说这个程序的使用方法

如果你有两个平面需要对照
【QG】命令设置两点
第1点设置在平面A的1轴-A轴交点
第2点设置在平面B的1轴-A轴交点
接下来你就可以使用【GG】命令
在两个平面的任意位置进行同一区域的“同步”

如果你面对的是一个多层建筑
当你的工作习惯良好时
这个程序就能最大化发挥出它的作用
很简单
只要各上下层的1-A交点间距完全一致
那么【QG】设置一次以后
你就可以在任意一层平面实现上下层的“同步”

前几天我发布过另一个小程序
先预设基点与终点
再选择对象直接完成复制
其实那个程序就是和这个程序配套的
稍微改一改
将预设基点与终点改为直接提取本程序的相对坐标
就可以实现任意上下平面同一区域的双向复制

;;;;;--------------------------------------------------------------------------------2011227说明

顶楼的QG、QQ程序在编制时有疏漏
现已将修复后程序放到了35楼
欢迎有兴趣的同学试用并反馈
若没有问题了
再更新到顶楼


 楼主| 发表于 2021-6-26 22:47:02 | 显示全部楼层
编程初期的想法和最后的成品
有一定的差距
所以代码有些凌乱
不影响使用就懒得优化了
发表于 2021-6-26 23:21:51 来自手机 | 显示全部楼层
明天试试效果,龙大师。
发表于 2021-6-27 17:34:43 | 显示全部楼层
好东西哇,非常感谢!!!!
发表于 2021-6-27 19:08:33 | 显示全部楼层
顶一个这个非常实用
发表于 2021-6-28 10:08:46 | 显示全部楼层
不知道是不是我操作问题,我用不了同步啊,当在其中一个视口内放大缩小显示,另外一个视口没有同步显示
 楼主| 发表于 2021-6-28 11:55:37 | 显示全部楼层
本程序的同步并非“实时”
反应器应该可以实现实时同步
但如果真这么做的话
估计会哭死吧
发表于 2021-6-28 13:25:59 | 显示全部楼层
大佬真给力!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-17 08:33 , Processed in 0.215701 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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