本帖最后由 zxjing 于 2020-11-5 23:34 编辑
一、程序功能 批量拉伸平面图形(主要是PL线)至三维实体。 具体为:把当前“打开状态”的每个图层上的图元(主要是闭合多段线)根据图层名称沿Z轴拉伸一定高度。(高度由图元所在的图层的名称“30-60m”的“-”和“m”之间的数值决定) 调用的命令为“EXTRUDE”, 工具条位置为“建模工具条\拉伸命令”。
二、面临问题 程序执行至遇到不能拉伸的“自相交曲线”时,程序提示“不能扫掠或拉伸自交的曲线”并中断运行,要求“重新选择拉伸对象”。 论坛里有类似的问题,只找到两种解决思路,但是没试出来怎么用,还请大咖们不吝赐教。思路①VLISP中vl-catch-all-apply 函数;思路②(defun *error*(msg) (princ "error: ") (princ msg) (princ))。
三、已知条件 因为CAD的图层是按照高度分层的,所以, ① 手动“拉伸”的话,可以“选层”,然后把本层所有图元统一拉伸一个高度。手动拉伸时,不能拉伸的图元(自相交曲线)会保持不变,但只要能拉伸的图元全部都能完成拉伸。(但程序执行时遇到“自交的曲线”就会中断,并一直要求输入待拉伸的图元(但并没有退出程序,也不是程序报错)) ② 剩下的“自相交曲线”可以通过工具条“拉伸”命令后面的“-presspull(按住并拖动)”命令来手动拉伸。
四、该问题的三种解决思路 1、 提前筛选自交曲线,不参与拉伸——目前网上找到的都不能满足需要,主要是两种情况: ① 只要是闭合的就认为是自交——(我的图元都是闭合多段线); ② 不能把“不能拉伸的图元”判定为自交曲线。 2、 跳过自交曲线,继续执行程序——能画个圈圈标注一下就更好了。这个不会弄,请求论坛大咖帮助啊。 3、CAD2018中调用“-presspull”命令——昨晚发现AutoCAD2018的“-presspull(按住并拖动)”命令可以直接操作图元而不需要像CAD2008一样“点击图元内部的点”才可以拉伸。但是没有试出来调用的方法,一直提示“-presspull”。
五、代码 - (defun C:PLLS ( / *error* error_bak );显示层按图层名高度 批量拉伸
- (print "\n请把需要拉伸的图层独立。不允许“空图层”和不能拉伸的图元!")
- ;;;获取打开状态的图层列表=====-=========================
- (setq n 1)
- (while (setq lay (tblnext "layer" (not lay)))
- (if (> (cdr (assoc 62 lay)) 0)
- (if (= n 1)
- (progn (setq date (cdr (assoc 2 lay)) ) (setq n 2))
- (print(setq date (strcat date " " (cdr (assoc 2 lay))) ))
- )
- ))
- ;;;获取打开状态的图层列表=====-=========================
-
- (setq i 0)
- (setq str1 (mapcar '(lambda(x)(set(read(strcat"dl"(itoa(setq i(1+ i)))))x))(read (strcat"(" date ")"))))
- (setq n 0)
- (repeat (length (setq str1(reverse (setq str1(mapcar 'vl-princ-to-string str1)))))
- (print (setq XStuceng;|显示图层|; (nth n str1))) ;获取一个打开的图层名
- (setq ss (ssget "x" (list(cons 8 XStuceng)))) ;按图层名称选择本层所有图元
- (sssetfirst nil ss)
-
- ;;; 获取图层名内“-”与“m”之间的数值作为拉伸的高度============
- ;;;(ascii "M(-+" ) ;查询ascii码
- (setq pos (vl-string-position 45 XStuceng))
- (setq gaodu (atoi(substr XStuceng (+ pos 2) (1- (- (vl-string-position 77 XStuceng) pos)))));返回以后的字串符
- ;;; 获取图层名内“-”与“m”之间的数值作为拉伸的高度============
-
- (command "layer" "s" XStuceng "")
- (setq m 0) ;序号的初值设为0
- (repeat (sslength ss);重复执行ss的长度的次数,即对象的个数
- (setq name (ssname ss m));得到选择集内第n个对象的图元名
- ;;; (setq ent (entget name));得到该对象的图元表
- ;;; 核心执行的“拉伸”命令在这里 ===========
- (if(=(command "extrude" name "" gaodu ) nil);这句判断好像直接执行了,一点判断作用也没有,否的情况从来没执行过
- ;;; (progn (setq ss2 (ssadd))
- ;;; (ssadd name ss2)
- ;;; (sssetfirst nil (ssadd (setq name (ssname ss (1- m))) ss2));
- (progn (setq m (1+ m))
- (princ m)
- )
- (progn(command "extrude" name "" gaodu )
- (setq m (1+ m))
- ;;; (setq m(+ m 100))
- )
- );if cishu_nil ;序号M的数量加1
- ;;; 核心执行的“拉伸”命令在这里 ===========
-
-
- )
-
- (setq n (1+ n))
- )
- (prin1)
- );程序结束
- (defun C:PLLS2 () ;查找批量拉伸失败的那个图元
- (command "regen")
- (setq ss2 (ssadd))
- (sssetfirst nil (ssadd (setq name (ssname ss (1- m))) ss2))
- )
六、实例文件
上面的这个文件下载后显示为“无效文件”,百度网盘连接为: 提取码:1234
1、文件中共有三个不能拉伸的“自交曲线”,打开线宽就可以很明显的看到。程序中断的时候用“plls2”就可以看到,但只能找到本次卡住的那一个。
2、示例文件在在三维视图下的,打开“视图”工具条即可调整视图角度,或者shift+鼠标中键。
|