18277132841 发表于 2025-4-29 11:46:59

模仿贱人工具箱的方向复制功能

想模仿贱人工具箱的方向复制功能,复制成功了,但是想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);清空选择集
)

hao3ren 发表于 2025-4-29 12:23:52

(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);清空选择集
)

layys 发表于 2025-4-29 15:18:13

(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)
)

lxw320 发表于 2025-4-29 16:12:55

StartUndoMark和EndUndoMark。

hhh454 发表于 2025-4-29 16:25:40

代码开头加上:(command "._undo" "_begin");;字面意思,你准备撤销到的当前状态,开始记录
代码结尾加上:(command "._undo" "_end");;字面意思,记录结尾,当你真的撤销,就返回开始记录的状态。
这是一个组合,中途不可退出,你完成一个记录过程和结尾,当你撤销时就会返回程序开始状态。

pizi158545086 发表于 2025-4-29 18:27:59

谢谢分享            

18277132841 发表于 2025-4-29 21:12:51

hao3ren 发表于 2025-4-29 12:23
(defun C:FZ ()
(setvar "cmdecho" 0)
(setq ss nil)


非常感谢,还得是lisp人多

18277132841 发表于 2025-4-29 21:14:38

layys 发表于 2025-4-29 15:18
(defun c:FZ (/ *error* main original_osnap original_echo undo_flag ss base_pt direction_pt step_dist ...

非常感谢............

18277132841 发表于 2025-4-29 21:15:51

hhh454 发表于 2025-4-29 16:25
代码开头加上:(command "._undo" "_begin");;字面意思,你准备撤销到的当前状态,开始记录
代码结尾加上 ...

感谢解答............
页: [1]
查看完整版本: 模仿贱人工具箱的方向复制功能