本帖最后由 f4800 于 2025-11-7 18:06 编辑
用ai生成了一个批量修剪的lsp
有别于ET工具 Extrim ,但是用途类似,可以选择需要修剪的对象
目标:
1、选择一条直线或 PL 线作为裁剪边界
2、在需要裁剪的一侧点击任意点
3、选择裁剪对象(直线或PL线)
4、然后裁剪选择的对象
欢迎测试体验、继续完善

网友答: 本帖最后由 guosheyang 于 2025-11-2 10:47 编辑
extrim命令(et)就可以满足你了网友答: 搞定了。。。。

网友答: 这个和TRT有什么区别网友答:
可行 这个不错 一直没发现网友答: 这个和TRT有什么区别
网友答:
TRT ? 我这没有这个命令。。。。。。。。。。网友答:
厉害了哥,一直想找这个功能的插件,没想到,这是CAD自带的吗?非常感谢
网友答:
好像只能用于裁剪直线网友答:
也是新手 还在摸索阶段
用ai生成了一个批量修剪的lsp
有别于ET工具 Extrim ,但是用途类似,可以选择需要修剪的对象
目标:
1、选择一条直线或 PL 线作为裁剪边界
2、在需要裁剪的一侧点击任意点
3、选择裁剪对象(直线或PL线)
4、然后裁剪选择的对象
欢迎测试体验、继续完善

- ; 快捷命令
- (defun c:ttt () (c:sidecut))
- (defun c:trr () (c:sidecut))
- (princ "\n命令已加载,输入 SIDECUT 或 trr 启动")
- (princ)
- (defun c:sidecut (/ *error* boundary pt1 pt2 side-pt is-left
- target-ents i ent int-points)
- (vl-load-com)
-
- ; 错误处理
- (defun *error* (msg)
- (if (not (member msg '("Function cancelled" "quit / exit abort" "")))
- (princ (strcat "\n错误: " msg))
- )
- (princ)
- )
-
- ; 1. 选择裁剪边界线
- (setq boundary nil)
- (while (not boundary)
- (princ "\n选择裁剪边界线(直线/LWPOLYLINE/PLINE): ")
- (setq temp-sel (entsel))
- (if temp-sel
- (progn
- (setq ent (car temp-sel)
- ent-type (cdr (assoc 0 (entget ent))))
- (if (member ent-type '("LINE" "LWPOLYLINE" "POLYLINE"))
- (setq boundary ent)
- (princ "\n无效对象!请选择直线或多段线。")
- )
- )
- (princ "\n未选择,请重新选择。")
- )
- )
- ; 获取端点
- (setq pt1 (vlax-curve-getStartPoint boundary)
- pt2 (vlax-curve-getEndPoint boundary))
-
- ; 2. 指定裁剪侧
- (princ "\n在需要裁剪的一侧点击任意点: ")
- (setq side-pt (getpoint))
- (if (not side-pt) (progn (princ "\n已取消") (exit)))
-
- ; 3. 判断点在直线的左侧还是右侧 - 使用叉积计算(避免 let 语法问题)
- (setq dx1 (- (car pt2) (car pt1)))
- (setq dy1 (- (cadr pt2) (cadr pt1)))
- (setq dx2 (- (car side-pt) (car pt1)))
- (setq dy2 (- (cadr side-pt) (cadr pt1)))
- (setq is-left (> (* dx1 dy2) (* dy1 dx2)))
- (princ (strcat "\n裁剪侧: " (if is-left "左侧" "右侧")))
-
- ; 4. 选择待裁剪对象
- (princ "\n选择需要裁剪的对象(直线/PL线等): ")
- (setq target-ents (ssget))
- (if (not target-ents) (progn (princ "\n未选择对象") (exit)))
-
- ; 5. 裁剪指定侧部分
- (setq i 0)
- (repeat (sslength target-ents)
- (setq ent (ssname target-ents i))
- (setq int-points (get-intersections ent boundary))
-
- (if (and int-points (> (length int-points) 0))
- (progn
- (princ (strcat "\n对象" (itoa (1+ i)) "找到" (itoa (length int-points)) "个交点"))
- ; 调用基于TRIM的裁剪函数
- (trim-with-trim ent boundary pt1 pt2 is-left)
- )
- (princ (strcat "\n对象" (itoa (1+ i)) "与边界线无交点,跳过"))
- )
- (setq i (1+ i))
- )
-
- (princ "\n裁剪完成!")
- (princ)
- )
- ; 辅助函数1:获取交点
- (defun get-intersections (obj boundary / obj-vla bnd-vla ints points i)
- (vl-catch-all-apply
- (function (lambda ()
- (setq obj-vla (vlax-ename->vla-object obj)
- bnd-vla (vlax-ename->vla-object boundary)
- ints (vlax-invoke obj-vla 'IntersectWith bnd-vla acExtendNone)
- points nil
- i 0
- )
- (while (< i (length ints))
- (setq points (cons (list (nth i ints) (nth (1+ i) ints)) points))
- (setq i (+ i 3))
- )
- (reverse points)
- ))
- nil
- )
- )
- ; 核心改进:使用TRIM命令裁剪
- (defun trim-with-trim (obj boundary pt1 pt2 is-left /
- obj-type obj-data pts int-points segs new-ents)
- (setq obj-type (cdr (assoc 0 (entget obj))))
-
- ; 仅处理直线和LWPOLYLINE(简化)
- (cond
- ; ===== 处理直线 =====
- ((= obj-type "LINE")
- (setq pts (list (cdr (assoc 10 (entget obj))) (cdr (assoc 11 (entget obj)))))
- (setq int-points (get-intersections obj boundary))
- (if (and int-points (= (length int-points) 1))
- (progn
- (setq segs (split-line-at-point pts (car int-points)))
- (process-segments segs pt1 pt2 is-left obj)
- )
- (princ "\n直线交点数量异常,跳过")
- )
- )
-
- ; ===== 处理 LWPOLYLINE(简化:只处理无弧段的)=====
- ((= obj-type "LWPOLYLINE")
- (princ "\n警告:LWPOLYLINE 裁剪暂未实现(可扩展)")
- ; 这里可以后续扩展,先跳过
- )
-
- (t
- (princ "\n不支持的对象类型,跳过")
- )
- )
- )
- ; 将直线按交点拆分为两段
- (defun split-line-at-point (pts ip)
- (list (list (car pts) ip) (list ip (cadr pts)))
- )
- ; 判断并保留/删除线段,同时复制原对象属性
- (defun process-segments (segs pt1 pt2 is-left orig-ent /
- ent-data new-ents layer lt ltype color lw weight)
- ; 获取原对象的所有DXF组码数据
- (setq ent-data (entget orig-ent))
-
- ; 提取常用属性(如果存在)
- (setq layer (cdr (assoc 8 ent-data))) ; 图层
- (setq lt (cdr (assoc 6 ent-data))) ; 线型(LTYPE)
- (setq color (cdr (assoc 62 ent-data))) ; 颜色(0=ByLayer, 正数=索引色, 负数=真彩色)
- (setq lw (cdr (assoc 370 ent-data))) ; 线宽(可选)
- (setq weight (cdr (assoc 39 ent-data))) ; 厚度(可选)
-
- (foreach seg segs
- (setq mid-pt (midpoint (car seg) (cadr seg)))
- (setq pt-is-left (is-point-left-of-line mid-pt pt1 pt2))
- ; 如果中点所在侧 ≠ 要裁剪的侧,则保留该段
- (if (/= pt-is-left is-left)
- (progn
- ; 构建新直线的DXF数据列表
- (setq new-line-data
- (list
- '(0 . "LINE")
- (cons 10 (car seg)) ; 起点
- (cons 11 (cadr seg)) ; 终点
- )
- )
-
- ; 有条件地添加属性(避免 nil 值)
- (if layer (setq new-line-data (append new-line-data (list (cons 8 layer)))))
- (if lt (setq new-line-data (append new-line-data (list (cons 6 lt)))))
- (if color (setq new-line-data (append new-line-data (list (cons 62 color)))))
- (if lw (setq new-line-data (append new-line-data (list (cons 370 lw)))))
- (if weight (setq new-line-data (append new-line-data (list (cons 39 weight)))))
-
- ; 创建新实体
- (entmake new-line-data)
- (setq new-ents (cons (entlast) new-ents))
- )
- )
- )
-
- ; 删除原始对象
- (entdel orig-ent)
- new-ents
- )
- ; 计算两点中点
- (defun midpoint (p1 p2)
- (mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
- )
- ; 辅助函数3:判断点是否在直线左侧
- (defun is-point-left-of-line (pt line-pt1 line-pt2)
- (> (- (* (- (car line-pt2) (car line-pt1)) (- (cadr pt) (cadr line-pt1)))
- (* (- (cadr line-pt2) (cadr line-pt1)) (- (car pt) (car line-pt1))))
- 0
- )
- )
网友答: 本帖最后由 guosheyang 于 2025-11-2 10:47 编辑
extrim命令(et)就可以满足你了网友答: 搞定了。。。。

- ; 快捷命令
- (defun c:ttt () (c:sidecut))
- (defun c:trr () (c:sidecut))
- (princ "\n命令已加载,输入 SIDECUT 或 trr 启动")
- (princ)
- (defun c:sidecut (/ *error* boundary pt1 pt2 side-pt is-left
- target-ents i ent int-points)
- (vl-load-com)
-
- ; 错误处理保持不变
- (defun *error* (msg)
- (if (not (member msg '("Function cancelled" "quit / exit abort" "")))
- (princ (strcat "\n错误: " msg))
- )
- (princ)
- )
-
- ; 1. 选择裁剪边界线(必须选中有效对象)
- (setq boundary nil)
- (while (not boundary)
- (princ "\n选择裁剪边界线(直线/LWPOLYLINE/PLINE): ")
- (setq temp-sel (entsel))
- (if temp-sel
- (progn
- (setq ent (car temp-sel)
- ent-type (cdr (assoc 0 (entget ent))))
- (if (member ent-type '("LINE" "LWPOLYLINE" "POLYLINE"))
- (setq boundary ent)
- (princ "\n无效对象!请选择直线或多段线。")
- )
- )
- (princ "\n未选择,请重新选择。")
- )
- )
- ; 获取端点
- (setq pt1 (vlax-curve-getStartPoint boundary)
- pt2 (vlax-curve-getEndPoint boundary))
-
- ; 2. 指定裁剪侧(保持不变)
- (princ "\n在需要裁剪的一侧点击任意点: ")
- (setq side-pt (getpoint))
- (if (not side-pt) (progn (princ "\n已取消") (exit)))
-
- (setq is-left
- (> (- (* (- (car pt2) (car pt1)) (- (cadr side-pt) (cadr pt1)))
- (* (- (cadr pt2) (cadr pt1)) (- (car side-pt) (car pt1))))
- 0)
- )
- (princ (strcat "\n裁剪侧: " (if is-left "左侧" "右侧")))
-
- ; 3. 选择待裁剪对象(保持不变)
- (princ "\n选择需要裁剪的对象(直线/PL线等): ")
- (setq target-ents (ssget))
- (if (not target-ents) (progn (princ "\n未选择对象") (exit)))
-
- ; 4. 裁剪指定侧部分(核心修改:使用TRIM命令)
- (setq i 0)
- (repeat (sslength target-ents)
- (setq ent (ssname target-ents i))
- (setq int-points (get-intersections ent boundary))
-
- (if (and int-points (> (length int-points) 0))
- (progn
- (princ (strcat "\n对象" (itoa (1+ i)) "找到" (itoa (length int-points)) "个交点"))
- ; 调用基于TRIM的裁剪函数
- (trim-with-trim ent boundary pt1 pt2 is-left)
- )
- (princ (strcat "\n对象" (itoa (1+ i)) "与边界线无交点,跳过"))
- )
- (setq i (1+ i))
- )
-
- (princ "\n裁剪完成!")
- (princ)
- )
- ; 辅助函数1:获取交点(保持不变)
- (defun get-intersections (obj boundary / obj-vla bnd-vla ints points i)
- (vl-catch-all-apply
- (function (lambda ()
- (setq obj-vla (vlax-ename->vla-object obj)
- bnd-vla (vlax-ename->vla-object boundary)
- ints (vlax-invoke obj-vla 'IntersectWith bnd-vla acExtendNone)
- points nil
- i 0
- )
- (while (< i (length ints))
- (setq points (cons (list (nth i ints) (nth (1+ i) ints)) points))
- (setq i (+ i 3))
- )
- (reverse points)
- ))
- nil
- )
- )
- ; 核心改进:使用TRIM命令裁剪
- ; 替换原来的 trim-with-trim 函数
- (defun trim-with-trim (obj boundary pt1 pt2 is-left /
- obj-type obj-data pts int-points segs new-ents)
- (setq obj-type (cdr (assoc 0 (entget obj))))
-
- ; 仅处理直线和LWPOLYLINE(简化)
- (cond
- ; ===== 处理直线 =====
- ((= obj-type "LINE")
- (setq pts (list (cdr (assoc 10 (entget obj))) (cdr (assoc 11 (entget obj)))))
- (setq int-points (get-intersections obj boundary))
- (if (and int-points (= (length int-points) 1))
- (progn
- (setq segs (split-line-at-point pts (car int-points)))
- (process-segments segs pt1 pt2 is-left obj)
- )
- (princ "\n直线交点数量异常,跳过")
- )
- )
-
- ; ===== 处理 LWPOLYLINE(简化:只处理无弧段的)=====
- ((= obj-type "LWPOLYLINE")
- (princ "\n警告:LWPOLYLINE 裁剪暂未实现(可扩展)")
- ; 这里可以后续扩展,先跳过
- )
-
- (t
- (princ "\n不支持的对象类型,跳过")
- )
- )
- )
- ; 将直线按交点拆分为两段
- (defun split-line-at-point (pts ip)
- (list (list (car pts) ip) (list ip (cadr pts)))
- )
- ; 判断并保留/删除线段
- ; 判断并保留/删除线段,同时复制原对象属性
- (defun process-segments (segs pt1 pt2 is-left orig-ent /
- ent-data new-ents layer lt ltype color lw weight)
- ; 获取原对象的所有DXF组码数据
- (setq ent-data (entget orig-ent))
-
- ; 提取常用属性(如果存在)
- (setq layer (cdr (assoc 8 ent-data))) ; 图层
- (setq lt (cdr (assoc 6 ent-data))) ; 线型(LTYPE)
- (setq color (cdr (assoc 62 ent-data))) ; 颜色(0=ByLayer, 正数=索引色, 负数=真彩色)
- (setq lw (cdr (assoc 370 ent-data))) ; 线宽(可选)
- (setq weight (cdr (assoc 39 ent-data))) ; 厚度(可选)
-
- (foreach seg segs
- (setq mid-pt (midpoint (car seg) (cadr seg)))
- (setq pt-is-left (is-point-left-of-line mid-pt pt1 pt2))
- ; 如果中点所在侧 ≠ 要裁剪的侧,则保留该段
- (if (/= pt-is-left is-left)
- (progn
- ; 构建新直线的DXF数据列表
- (setq new-line-data
- (list
- '(0 . "LINE")
- (cons 10 (car seg)) ; 起点
- (cons 11 (cadr seg)) ; 终点
- )
- )
-
- ; 有条件地添加属性(避免 nil 值)
- (if layer (setq new-line-data (append new-line-data (list (cons 8 layer)))))
- (if lt (setq new-line-data (append new-line-data (list (cons 6 lt)))))
- (if color (setq new-line-data (append new-line-data (list (cons 62 color)))))
- (if lw (setq new-line-data (append new-line-data (list (cons 370 lw)))))
- (if weight (setq new-line-data (append new-line-data (list (cons 39 weight)))))
-
- ; 创建新实体
- (entmake new-line-data)
- (setq new-ents (cons (entlast) new-ents))
- )
- )
- )
-
- ; 删除原始对象
- (entdel orig-ent)
- new-ents
- )
- ; 计算两点中点
- (defun midpoint (p1 p2)
- (mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
- )
- ; 辅助函数3:判断点是否在直线左侧(保持不变)
- (defun is-point-left-of-line (pt line-pt1 line-pt2)
- (> (- (* (- (car line-pt2) (car line-pt1)) (- (cadr pt) (cadr line-pt1)))
- (* (- (cadr line-pt2) (cadr line-pt1)) (- (car pt) (car line-pt1))))
- 0)
- )
网友答: 这个和TRT有什么区别网友答:
guosheyang 发表于 2025-11-2 10:39
extrim命令(et)就可以满足你了
可行 这个不错 一直没发现网友答: 这个和TRT有什么区别
网友答:
阿猪蛋 发表于 2025-11-3 15:32
这个和TRT有什么区别
TRT ? 我这没有这个命令。。。。。。。。。。网友答:
guosheyang 发表于 2025-11-2 10:39
extrim命令(et)就可以满足你了
厉害了哥,一直想找这个功能的插件,没想到,这是CAD自带的吗?非常感谢
网友答:
好像只能用于裁剪直线网友答:
nzdog 发表于 2025-11-4 12:35
好像只能用于裁剪直线
也是新手 还在摸索阶段