明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 278|回复: 8

[提问] 模仿贱人工具箱的方向复制功能

[复制链接]
发表于 昨天 11:46 | 显示全部楼层 |阅读模式
想模仿贱人工具箱的方向复制功能,复制成功了,但是想U撤销时只能一次撤销一个复制对象,要按很多次,不能像贱人工具箱那样一次全部撤销,大佬们帮看看这个怎么解决?


(defun C:FZ ()
  (setvar "cmdecho" 0)
  (setq ss nil)
  (setq ss (ssget));选择对象
  (setq P1 (getpoint "\n复制基点:"))
  (setq P2 (getpoint "\n复制方向:" P1))(terpri)

  ;设置复制间距
  (setq JJtemp JJ)
  (if (= JJtemp nil)(setq JJtemp 10))
  (setq JJ (getdist (strcat "\n复制间距<" (rtos JJtemp 2 3) ">:")))
  (if (= JJ nil)(setq JJ JJtemp))

  ;设置复制次数
  (setq CStemp CS)
  (if (= CStemp nil)(setq CStemp 10))
  (setq CS (getint (strcat "\n复制数量<" (itoa CStemp) ">:")))
  (if (= CS nil)(setq CS CStemp))

  (setq ANG (angle P1 P2));计算方向角
  (setq OM (getvar "OSMODE"));保存捕抓模式
  (setvar "OSMODE" 0);关闭捕抓
  (setq JL 0);初始化距离
  (repeat CS;重复复制
    (setq JL (+ JL JJ));第i次复制距离
    (setq newPt (polar P1 ANG JL));第i次复制点
    (command "copy" ss "" P1 newPt);复制
  )
  (setvar "OSMODE" OM);恢复捕抓模式
  (setq ss nil);清空选择集
)

回复

使用道具 举报

发表于 昨天 12:23 | 显示全部楼层
(defun C:FZ ()
  (setvar "cmdecho" 0)
  (setq ss nil)
  (setq ss (ssget));选择对象
  (setq P1 (getpoint "\n复制基点:"))
  (setq P2 (getpoint "\n复制方向:" P1))(terpri)

  ;设置复制间距
  (setq JJtemp JJ)
  (if (= JJtemp nil)(setq JJtemp 10))
  (setq JJ (getdist (strcat "\n复制间距<" (rtos JJtemp 2 3) ">:")))
  (if (= JJ nil)(setq JJ JJtemp))

  ;设置复制次数
  (setq CStemp CS)
  (if (= CStemp nil)(setq CStemp 10))
  (setq CS (getint (strcat "\n复制数量<" (itoa CStemp) ">:")))
  (if (= CS nil)(setq CS CStemp))

  (setq ANG (angle P1 P2));计算方向角
  (setq OM (getvar "OSMODE"));保存捕抓模式
  (setvar "OSMODE" 0);关闭捕抓
  (setq JL 0);初始化距离
(command "undo" "be")
  (repeat CS;重复复制
    (setq JL (+ JL JJ));第i次复制距离
    (setq newPt (polar P1 ANG JL));第i次复制点
    (command "copy" ss "" P1 newPt);复制
  )
(command "undo" "e")
  (setvar "OSMODE" OM);恢复捕抓模式
  (setq ss nil);清空选择集
)
回复 支持 反对

使用道具 举报

发表于 昨天 15:18 | 显示全部楼层
(defun c:FZ (/ *error* main original_osnap original_echo undo_flag ss base_pt direction_pt step_distance copy_count)
  ;; 错误处理函数
  (defun *error* (msg)
    (if (and (= undo_flag 1)(= (logand (getvar "UNDOCTL") 8) 8)) ; 检查undo组状态
      (command-s "_.undo" "_end") ; 使用安全命令结束undo组
    )
    (setvar "OSMODE" original_osnap) ; 恢复对象捕捉
    (setvar "CMDECHO" original_echo) ; 恢复命令回显
    (princ (strcat "\n操作终止: " msg))
    (princ)
  )

  ;; 主逻辑函数
  (defun main ()
    (setq original_osnap (getvar "OSMODE")
          original_echo (getvar "CMDECHO")
          undo_flag 0)
   
    (command "_.undo" "_begin") ; 开始事务
    (setq undo_flag 1)
   
    (if (setq ss (ssget))
      (progn
        ;; 用户输入阶段
        (setq base_pt (getpoint "\n选择复制基点: "))
        (setq direction_pt (getpoint base_pt "\n指定方向点: "))
        
        ;; 带默认值的输入处理
        (setq step_distance
          (cond
            ((getdist (strcat "\n输入复制间距<10.0>: ")) )
            (10.0)
          )
        )
        (setq copy_count
          (cond
            ((getint "\n输入复制数量<10>: ") )
            (10)
          )
        )

        ;; 执行复制操作
        (setvar "OSMODE" 0)
        (setvar "CMDECHO" 0)
        (setq direction_angle (angle base_pt direction_pt)
              total_distance 0.0)
        
        (repeat copy_count
          (setq total_distance (+ total_distance step_distance)
                target_pt (polar base_pt direction_angle total_distance))
          (command "_.copy" ss "" "_non" base_pt "_non" target_pt)
        )
      )
      (princ "\n未选择有效对象")
    )
   
    (command "_.undo" "_end") ; 正常结束事务
    (setq undo_flag 0)
  )

  ;; 程序入口
  (vl-load-com) ; 加载VL扩展
  (setvar "CMDECHO" 0)
  (main)
  (setvar "CMDECHO" original_echo)
  (princ (strcat "\n成功创建 " (itoa copy_count) " 个副本(输入UNDO可一次性撤销)"))
  (princ)
)
回复 支持 反对

使用道具 举报

发表于 昨天 16:12 | 显示全部楼层
StartUndoMark和EndUndoMark。
回复 支持 反对

使用道具 举报

发表于 昨天 16:25 | 显示全部楼层
代码开头加上:(command "._undo" "_begin");;字面意思,你准备撤销到的当前状态,开始记录
代码结尾加上:(command "._undo" "_end");;字面意思,记录结尾,当你真的撤销,就返回开始记录的状态。
这是一个组合,中途不可退出,你完成一个记录过程和结尾,当你撤销时就会返回程序开始状态。
回复 支持 反对

使用道具 举报

发表于 昨天 18:27 | 显示全部楼层
谢谢分享            
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 21:12 | 显示全部楼层
hao3ren 发表于 2025-4-29 12:23
(defun C:FZ ()
  (setvar "cmdecho" 0)
  (setq ss nil)

非常感谢,还得是lisp人多
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 21:14 | 显示全部楼层
layys 发表于 2025-4-29 15:18
(defun c:FZ (/ *error* main original_osnap original_echo undo_flag ss base_pt direction_pt step_dist ...

非常感谢............
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 21:15 | 显示全部楼层
hhh454 发表于 2025-4-29 16:25
代码开头加上:(command "._undo" "_begin");;字面意思,你准备撤销到的当前状态,开始记录
代码结尾加上 ...

感谢解答............
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-30 10:16 , Processed in 0.178027 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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