模仿贱人工具箱的方向复制功能
想模仿贱人工具箱的方向复制功能,复制成功了,但是想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);清空选择集
)
(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);清空选择集
) (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)
)
StartUndoMark和EndUndoMark。 代码开头加上:(command "._undo" "_begin");;字面意思,你准备撤销到的当前状态,开始记录
代码结尾加上:(command "._undo" "_end");;字面意思,记录结尾,当你真的撤销,就返回开始记录的状态。
这是一个组合,中途不可退出,你完成一个记录过程和结尾,当你撤销时就会返回程序开始状态。 谢谢分享 hao3ren 发表于 2025-4-29 12:23
(defun C:FZ ()
(setvar "cmdecho" 0)
(setq ss nil)
非常感谢,还得是lisp人多 layys 发表于 2025-4-29 15:18
(defun c:FZ (/ *error* main original_osnap original_echo undo_flag ss base_pt direction_pt step_dist ...
非常感谢............ hhh454 发表于 2025-4-29 16:25
代码开头加上:(command "._undo" "_begin");;字面意思,你准备撤销到的当前状态,开始记录
代码结尾加上 ...
感谢解答............
页:
[1]