本帖最后由 qifeifei 于 2025-6-27 13:43 编辑
平时做平面图衣柜
需要用到这个代码;使用AI写的代码 调试了很多了 效果也不太理想
有时候可能达到自己想要的效果 有时候又抽风 求优化
成功展示:
网友答: 太感动了 我终于研制成了
网友答: 哈哈,怎么感觉现在还比以前糟糕,以前都是求代码,
起码大家的代码都没有问题.
现在是拿着代码让别人改,别人还得从头看一次你的代码,
你代码的函数又不是别人的函数库,还得从头学一次.
真的把这个工作想得太简单了...
不是懂代码的用这个工具会让全部人都感受到痛苦.网友答:
好吧
我是有研究了部分;但是效果调试的不理想,才发出来
比较多的代码 我调试好的;我都自己用了 没发了
那等我空了 在研究下
网友答:
;; 这种效果?
网友答:
大佬,求代码
网友答:
至少方向对了 回头在研究剪切
平时做平面图衣柜
需要用到这个代码;使用AI写的代码 调试了很多了 效果也不太理想
有时候可能达到自己想要的效果 有时候又抽风 求优化

- (defun c:T5 (/ ss ent obj p1 p2 dir unit len p2new leftEnt rightEnt left right
- newp1 newp2 mid allLines i crossEnt crossP1 crossP2 x1 x2
- y1 y2 ip1 ip2)
- (vl-load-com)
- (prompt "\n[T5] 开始运行命令...")
- ;; 选择竖向直线
- (if (setq ss (ssget '((0 . "LINE,LWPOLYLINE"))))
- (progn
- (setq ent (ssname ss 0)
- obj (vlax-ename->vla-object ent)
- p1 (vlax-get obj 'StartPoint)
- p2 (vlax-get obj 'EndPoint)
- dir (mapcar '- p2 p1)
- len (distance p1 p2))
- ;; 判断竖线
- (if (< (abs (car dir)) 0.01)
- (progn
- (setq unit (mapcar '(lambda (x) (/ x len)) dir))
- (setq p2new (mapcar '+ p2 (mapcar '(lambda (x) (* x 18.0)) unit)))
- (vlax-put obj 'EndPoint p2new)
- (prompt (strcat "\n[T5] 已延申到新终点: "
- (rtos (car p2new) 2 2) ", "
- (rtos (cadr p2new) 2 2)))
- ;; 左右偏移
- (vla-offset obj 18.0)
- (setq rightEnt (entlast))
- (vla-offset obj -18.0)
- (setq leftEnt (entlast))
- ;; 获取偏移线坐标
- (setq right (vlax-ename->vla-object rightEnt))
- (setq left (vlax-ename->vla-object leftEnt))
- (setq newp1 (vlax-get obj 'StartPoint))
- (setq newp2 (vlax-get obj 'EndPoint))
- (setq mid (mapcar '(lambda (a b) (/ (+ a b) 2.0)) newp1 newp2))
- ;; 获取左右偏移的X范围
- (setq x1 (car (vlax-get left 'StartPoint)))
- (setq x2 (car (vlax-get right 'StartPoint)))
- (if (> x1 x2) (setq tmp x1 x1 x2 x2 tmp)) ; 交换x1 x2顺序
- ;; 查找在左右偏移线之间的横线
- (setq allLines (ssget "_X" '((0 . "LINE,LWPOLYLINE"))))
- (setq i -1)
- (while (and allLines (setq crossEnt (ssname allLines (setq i (1+ i)))))
- (setq crossObj (vlax-ename->vla-object crossEnt))
- (setq crossP1 (vlax-get crossObj 'StartPoint))
- (setq crossP2 (vlax-get crossObj 'EndPoint))
- ;; 横向判断:y 坐标相同,x 跨越 x1 ~ x2
- (if (and (equal (cadr crossP1) (cadr crossP2) 0.01)
- (< (min (car crossP1) (car crossP2)) x1)
- (> (max (car crossP1) (car crossP2)) x2))
- (progn
- ;; 计算交点:在左右偏移线 x1 和 x2 的交点处 break
- (setq y (cadr crossP1))
- (setq ip1 (list x1 y 0.0))
- (setq ip2 (list x2 y 0.0))
- ;; 执行 break
- (command "_.break" crossEnt ip1 ip2)
- (prompt "\n[T5] 成功剪切一条横线")
- (setq i (sslength allLines)) ; 跳出循环,只剪一条
- )
- )
- )
- )
- (prompt "\n[T5] 请只选择一条竖向的 LINE 或 LWPOLYLINE.")
- )
- )
- (prompt "\n[T5] 没有选择任何对象")
- )
- (princ)
- )
网友答: 太感动了 我终于研制成了
网友答: 哈哈,怎么感觉现在还比以前糟糕,以前都是求代码,
起码大家的代码都没有问题.
现在是拿着代码让别人改,别人还得从头看一次你的代码,
你代码的函数又不是别人的函数库,还得从头学一次.
真的把这个工作想得太简单了...
不是懂代码的用这个工具会让全部人都感受到痛苦.网友答:
你有种再说一遍 发表于 2025-6-27 18:03
哈哈,怎么感觉现在还比以前糟糕,以前都是求代码,
起码大家的代码都没有问题.
好吧
我是有研究了部分;但是效果调试的不理想,才发出来
比较多的代码 我调试好的;我都自己用了 没发了

那等我空了 在研究下
网友答:
qifeifei 发表于 2025-6-27 20:18
好吧
我是有研究了部分;但是效果调试的不理想,才发出来
比较多的代码 我调试好的;我都自己用了 没 ...
;; 这种效果?
网友答:
xyp1964 发表于 2025-6-29 20:46
;; 这种效果?
大佬,求代码
网友答:

- ; --- 全局错误处理函数 ---
- (defun *error* (msg)
- (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,*EXIT*,")))
- (princ (strcat "\n[Error] 程序出错或中断: " msg))
- )
- ; 恢复系统变量
- (if *old_cmdecho* (setvar "CMDECHO" *old_cmdecho*))
- (if *old_osmode* (setvar "OSMODE" *old_osmode*))
- (princ)
- )
- ; --- 辅助函数:计算两条线段的交点 ---
- ; ent1, ent2: 实体名
- ; 返回: 交点坐标 (x y z) 或 nil
- (defun get_line_intersection (ent1 ent2 / data1 data2 pt10 pt11 pt20 pt21 inters_pt)
- (setq data1 (entget ent1))
- (setq data2 (entget ent2))
- (setq pt10 (cdr (assoc 10 data1)))
- (setq pt11 (cdr (assoc 11 data1)))
- (setq pt20 (cdr (assoc 10 data2)))
- (setq pt21 (cdr (assoc 11 data2)))
- ; 计算线段交点 (nil 表示线段)
- (setq inters_pt (inters pt10 pt11 pt20 pt21 nil))
- inters_pt ; 返回交点或 nil
- )
- ; --- 主函数 ---
- (defun c:T5 (/ *old_cmdecho* *old_osmode* ss ent_original ent_data_original start_point_original end_point_original new_end_point mid_point_extended ent_left ent_right offset_dist selection_buffer ss_candidate_lines ent_hline pt_left pt_right i ent_check data_check pt1_check pt2_check mid_seg_ent_id found_mid_seg)
- ; --- 保存系统变量 ---
- (setq *old_cmdecho* (getvar "CMDECHO"))
- (setq *old_osmode* (getvar "OSMODE"))
- (setvar "CMDECHO" 0) ; 关闭命令行回显
- (setvar "OSMODE" 0) ; 关闭对象捕捉,确保点精确
- ; --- 参数设置 ---
- (setq offset_dist 18.0) ; 偏移距离和延伸距离
- (setq selection_buffer 50.0) ; 用于选择水平线的缓冲区大小
- ; --- 1. 选择原始直线 ---
- (princ "\n请选择一条直线: ")
- (setq ss (ssget ":S" '((0 . "LINE")))) ; ":S" 限制只能选择一个实体
- ; --- 2. 检查是否选择了对象 ---
- (if ss
- (progn
- ; --- 3. 获取原始实体信息 ---
- (setq ent_original (ssname ss 0))
- (setq ent_data_original (entget ent_original))
- (setq start_point_original (cdr (assoc 10 ent_data_original)))
- (setq end_point_original (cdr (assoc 11 ent_data_original)))
- ; --- 4. 延伸操作 (向北Y+) ---
- ; 确定哪个端点是"北端点" (Y值较大)
- (if (> (cadr start_point_original) (cadr end_point_original))
- (progn
- ; start_point_original 是北端点
- (setq new_end_point (list (car start_point_original) (+ (cadr start_point_original) offset_dist) (caddr start_point_original)))
- (setq ent_data_original (subst (cons 10 new_end_point) (assoc 10 ent_data_original) ent_data_original))
- ; mid_point_extended 应该是原始线段的中点
- (setq mid_point_extended (list
- (/ (+ (car end_point_original) (car new_end_point)) 2.0)
- (/ (+ (cadr end_point_original) (cadr new_end_point)) 2.0)
- (/ (+ (caddr end_point_original) (caddr new_end_point)) 2.0)
- )
- )
- )
- (progn
- ; end_point_original 是北端点
- (setq new_end_point (list (car end_point_original) (+ (cadr end_point_original) offset_dist) (caddr end_point_original)))
- (setq ent_data_original (subst (cons 11 new_end_point) (assoc 11 ent_data_original) ent_data_original))
- ; mid_point_extended 应该是原始线段的中点
- (setq mid_point_extended (list
- (/ (+ (car start_point_original) (car new_end_point)) 2.0)
- (/ (+ (cadr start_point_original) (cadr new_end_point)) 2.0)
- (/ (+ (caddr start_point_original) (caddr new_end_point)) 2.0)
- )
- )
- )
- )
- (entmod ent_data_original) ; 应用修改
- (princ "\n[Info] 选定直线已向北延伸18个单位。")
- ; --- 5. 向左偏移 ---
- (setq offset_point_left (list (- (car mid_point_extended) offset_dist) (cadr mid_point_extended) (caddr mid_point_extended)))
- (command "_.UNDO" "BE") ; 开始 UNDO 组
- (command "_.OFFSET" offset_dist ent_original offset_point_left "")
- (if (and (= (getvar 'CMDNAMES) "") (entlast)) ; 检查 OFFSET 是否成功
- (progn
- (setq ent_left (entlast))
- (princ "\n[Info] 向左偏移18个单位完成。")
- )
- (princ "\n[Warning] 向左偏移可能失败。")
- )
- ; --- 6. 向右偏移 ---
- (setq offset_point_right (list (+ (car mid_point_extended) offset_dist) (cadr mid_point_extended) (caddr mid_point_extended)))
- (command "_.OFFSET" offset_dist ent_original offset_point_right "")
- (if (and (= (getvar 'CMDNAMES) "") (entlast)) ; 检查 OFFSET 是否成功
- (progn
- (setq ent_right (entlast))
- (princ "\n[Info] 向右偏移18个单位完成。")
- )
- (princ "\n[Warning] 向右偏移可能失败。")
- )
- ; --- 7. 打断并删除水平线中间段 ---
- (princ "\n[Info] 开始查找并删除水平线中间段...")
- ; --- 8. 计算选择窗口 ---
- (setq min_x (- (car offset_point_left) selection_buffer))
- (setq max_x (+ (car offset_point_right) selection_buffer))
- (setq min_y (- (cadr mid_point_extended) selection_buffer))
- (setq max_y (+ (cadr mid_point_extended) selection_buffer))
- (setq corner1_window (list min_x max_y 0.0)) ; 左上
- (setq corner2_window (list max_x min_y 0.0)) ; 右下
- ; --- 9. 使用交叉窗口选择候选线 ---
- (setq ss_candidate_lines (ssget "C" corner1_window corner2_window '((0 . "LINE"))))
-
- (if ss_candidate_lines
- (progn
- (princ (strcat "\n[Info] 找到 " (itoa (sslength ss_candidate_lines)) " 条候选线段。"))
- (setq i 0)
- (repeat (sslength ss_candidate_lines)
- (setq ent_hline (ssname ss_candidate_lines i))
- ; --- 10. 排除原始线、左偏移线、右偏移线本身 ---
- (if (and (/= ent_hline ent_original) (/= ent_hline ent_left) (/= ent_hline ent_right))
- (progn
- ; --- 11. 计算交点 ---
- (setq pt_left (get_line_intersection ent_hline ent_left))
- (setq pt_right (get_line_intersection ent_hline ent_right))
- ; --- 12. 如果与两条竖线都有交点 ---
- (if (and pt_left pt_right)
- (progn
- (princ (strcat "\n[Info] 处理水平线..."))
- ; --- 13. 执行两次打断 ---
- ; 使用 _non 过滤器确保点精确传递
- (command "_.BREAK" ent_hline (list '_non pt_left) (list '_non pt_left))
- (if (/= (getvar 'CMDNAMES) "")
- (princ "\n[Warning] 第一次 BREAK 可能失败。")
- )
- (command "_.BREAK" ent_hline (list '_non pt_right) (list '_non pt_right))
- (if (/= (getvar 'CMDNAMES) "")
- (princ "\n[Warning] 第二次 BREAK 可能失败。")
- )
- ; --- 14. 查找并删除中间段 ---
- ; 再次选择窗口内的线,查找端点为 P1 和 P2 的线段
- (setq ss_post_break (ssget "C" corner1_window corner2_window '((0 . "LINE"))))
- (setq found_mid_seg nil) ; 标记是否找到
- (if ss_post_break
- (progn
- (setq j 0)
- (repeat (sslength ss_post_break)
- (setq ent_check (ssname ss_post_break j))
- (setq data_check (entget ent_check))
- (setq pt1_check (cdr (assoc 10 data_check)))
- (setq pt2_check (cdr (assoc 11 data_check)))
- ; 检查端点是否为 P1 和 P2 (顺序无关,带容差)
- (if (or
- (and (< (distance pt1_check pt_left) 1e-4) (< (distance pt2_check pt_right) 1e-4))
- (and (< (distance pt1_check pt_right) 1e-4) (< (distance pt2_check pt_left) 1e-4))
- )
- (progn
- (setq found_mid_seg T)
- (entdel ent_check) ; 删除找到的中间段
- (princ "\n[Info] 已删除中间段。")
- (setq j (sslength ss_post_break)) ; 找到即退出
- )
- )
- (setq j (1+ j))
- ) ; repeat j
- ) ; progn if ss_post_break
- ) ; if ss_post_break
- (if (not found_mid_seg)
- (princ "\n[Warning] 未能找到中间段进行删除。")
- )
- ) ; if (and pt_left pt_right)
- ) ; if (/= ent_...)
- ) ; progn
- ) ; if ss_candidate_lines
- (setq i (1+ i))
- ) ; repeat i
- (princ "\n[Info] 候选线处理完成。")
- )
- (princ "\n[Info] 未找到候选线段。")
- ) ; if ss_candidate_lines
- (command "_.UNDO" "E") ; 结束 UNDO 组
- (command "_.REGEN") ; 最终重生成图形
- (princ "\n[Info] 所有操作已完成。")
- )
- ; --- 如果没有选择对象 ---
- (princ "\n[Error] 错误: 请先选择一条直线。")
- )
- ; --- 恢复系统变量 ---
- (setvar "CMDECHO" *old_cmdecho*)
- (setvar "OSMODE" *old_osmode*)
- (princ)
- )
- (princ "\nT5命令已加载。命令: T5")
- (princ)