masterlong 发表于 2016-8-7 16:10:10

模型绘图、布局出图的演示代码

本帖最后由 masterlong 于 2016-9-9 14:44 编辑

一直在模型中绘图出图
最近一个项目的地下室太大
只能采用布局出图
于是写了这个代码
放上来供大家参考

单位的图框是块
图框采用其它形式的同学
请自行修改有关代码
比如可以
多边形与图框做成块布局中插入
方法并不唯一

对布局其实我也并不熟悉
论坛上总看到人说
布局打印多方便啥的
也没有切身体会
看了网上的布局打印教程
说句实在话
感觉是相当麻烦
做这个程序的目的
也仅仅让只熟悉模型的同学
能够在布局中象模型一样执行打印
望熟悉布局的同学多提意见(vl-load-com)
(setq *ent2obj*         vlax-Ename->Vla-Object
    *acad*          (vlax-get-acad-object)
    *doc*          (vla-get-ActiveDocument *acad*)
    *Layouts*      (vla-get-Layouts *doc*)
)



;;模型中绘制多边形视口(不专门绘制,将现有闭合的pl线转成“zzz___多边形视口”图层也可以)
(defun c:ppp1( / p1 p2 p3 p4 templ )
(setvar "cmdecho" 0)
(command "undo" "g")
(command "ucs" "")
(command "layer" "m" "zzz___图框内框线" "p" "n" "zzz___图框内框线" "c" "19" "" "")
(command "layer" "m" "zzz___多边形视口" "p" "n" "zzz___多边形视口" "c" "252" "" "")
(if (and
      (setq p1 (getpoint "绘制多边形视口第1点 : "))
      (setq p2 (getpoint p1 "下一点 : "))
      (null (command "line" "non" p1 "non" p2 ""))
      (setq templ (entlast))
      (setq p3 (getpoint p2 "下一点 : "))
    )
    (progn
      (entdel templ)
      (command "pline" "non" p1 "w" 0 0 "non" p2 "non" p3)
      (while (setq p4 (getpoint p3 "下一点 : "))
      (command "non" (setq p3 p4))
      )
      (command "c")
    )
    (if p2 (entdel templ))
)
(command "undo" "e")
;;(princ "重复执行本程序,继续绘制其它多边形视口")

(princ "\n|\n|\n 模型绘图、布局出图的演示代码   by masterlong")
(princ)
)

;;插入图框,要求图框能完全包含多边形视口
(defun c:ppp2()
;;...略...
(princ)
)

;;布局批量生成视口并配置相应图框
(defun c:ppp3()
(setvar "cmdecho" 0)
(command "undo" "g")
(command "ucs" "")
(command "layer" "m" "zzz___图框内框线" "p" "n" "zzz___图框内框线" "c" "19" "" "")

(princ "按图纸顺序,依次选择图框以生成用于批打印的布局....")
(setq ss (ssget '((0 . "insert")(2 . "QGY_V16_TK-*"))))      ;;单位图框为块,对使用PL围合线作图框的同学,自行修改相应代码
(command "zoom" "e")

;;获取每个图框的块名、角度和比例,生成tkdatlist用于随后生成布局
(setq tkdatlist '())
(foreach tkb (reverse (ss2list ss))
    ;;取图框块名、比例、角度(未校验图框的角度是否0.5PI的整数倍)
    (setq entlist (entget tkb))
    (setq tkname(cdr (assoc2 entlist)))
    (setq tkinssc(cdr (assoc 41 entlist)))
    (setq tkinsang (cdr (assoc 50 entlist)))
   
    ;;取图框两角点————最好是内框————因为是演示代码,取的是外框
    (setq box (entbox tkb))
    (setq tkp1 (carbox))
    (setq tkp2 (cadr box))
   
    ;;绘制非打印图框线,事后可不删,用于绘图时提示用
    (command "rectang" "non" tkp1 "non" tkp2 "change" (entlast) "" "p" "c" 19 "")
   
    ;;是否包含特定的多边形
    ;;两种情况下的tkdatlist构成是不同的
    ;;tkdatlist子表
    ;;有特定多边形时'(图框块名 比例 角度 图框角点1 图框角点2 '(多边形视口块名 '(包围盒角点1 角点2)))
    ;;无特定多边形时'(图框块名 比例 角度 图框角点1 图框角点2 图框线图元名)
    (if (setq vpplss (ssget "w" tkp1 tkp2 '((0 . "LWPOLYLINE")(8 . "zzz___多边形视口"))))
      (progn
      (setq vppl (ssname vpplss 0))      ;;未校验pl是否唯一,是否闭合
      
      ;;vppl做时间块,便于生成视口时调用
      (setq 时间 (getvar "cdate"))
      (setq 时间 (rtos 时间 2 8))
      (setq 组合块名 (strcat "多边形视口块" "___" (substr 时间 14)))
      (command "block" 组合块名 "non" tkp1 vppl "" "oops")
      
      (setq tkdatlist (cons (list tkname tkinssc tkinsang tkp1 tkp2 (list 组合块名 (entbox vppl))) tkdatlist))
      
      )
      (setq tkdatlist (cons (list tkname tkinssc tkinsang tkp1 tkp2 (entlast)) tkdatlist))
    )   
)
(command "erase" ss "")    ;;删除模型中的图框


;;生成专用新布局页面并激活(未测试布局是否已存在)
(setq vpp_vplot (vla-add *Layouts* "v16_布局批打印"))
(vla-put-ActiveLayout *doc* vpp_vplot)
(setvar "clayer" "z_图框")


;;布局插入图框,建立视口并锁定
(setq popopo '(0 0))
(foreach x tkdatlist
    (command "PSPACE")
   
    ;;插入图框
    (command "insert" (nth 0 x) "non" popopo (nth 1 x) "" (angtos (nth 2 x) 0 9))
    (setq tkb (entlast))
    (setq box (entbox tkb))
    (setq box_w (- (car (cadr box)) (car (car box))))
    (command "move" tkb "" "0,0" (strcat (rtos box_w) "<0"))
    (setq popopo (polar popopo 0 (+ box_w 100000)))
   
    ;;获取插入图框的两角点
    (setq box (entbox tkb))
    (setq tkpp1 (carbox))
    (setq tkpp2 (cadr box))
   
    ;;根据tkdatlist子表第6项,执行不同的流程
    (if (= (type (nth 5 x)) 'ENAME)
      ;;以图框线建立视口并锁定
      ;;特别提醒:布局中建立视口以后,视口是可以拉伸进行调整的
      (progn
      (princ "\n图框线建立视口")
      (command "_mview" "non" tkpp1 "non" tkpp2)
      (command "PSPACE" "zoom" "e")
      (command "_mspace")
      (command "zoom" "w" "non" (nth 3 x) "non" (nth 4 x))
      (command "_mview" "l" "on" "l" "")
      )
      ;;以预设多边形建立视口并锁定,pu对应的时间块
      ;;多边形建立视口的好处是,图面看起来不是那么的满,可以在空白处放一些大样啊、说明啥的
      ;;另外多边形视口很难包括轴号,需要在布局中另外“套”上轴号等
      ;;可以采用模型内多边形的某一角点作基点,复制轴号到布局,再移动到图框内,本演示程序不包含此部分代码————手动操作也不复杂
      (progn
      (princ "\n预设多边形建立视口")
      (command "PSPACE" "zoom" "e")
      (setvar "qaflags" 0)
      (command "insert" (car (nth 5 x)) "non" tkpp1 1 1 0 "explode" (entlast) "purge" "b" (car (nth 5 x)) "n")
      (setq thevppl (entlast))
      (command "_mview" "o" thevppl)
      (command "_mspace")
      ;;下面这句代码很重要,使得模型绘制的多边形和布局的多边形视口完全重合
      (command "zoom" "w" "non" (car (cadr (nth 5 x))) "non" (cadr (cadr (nth 5 x))))
      (command "_mview" "l" "on" thevppl "")
      )
    )
)
(command "PSPACE" "zoom" "e")
(command "undo" "e")

(princ "\n|\n|\n 模型绘图、布局出图的演示代码   by masterlong")
(princ)
)


;;单个物体的最小(正交)包围框---------------------------------这个程序在遇到无法显示的图元时,还是会出错的,比如形。天正图元会不会也不支持,未测试
(defun entbox ( ent / ll ur )
(vla-getboundingbox (*ent2obj* ent) 'll 'ur)
(mapcar 'vlax-safearray->list (list ll ur))
)




(princ "\n|\n|\n 模型绘图、布局出图的演示代码   by masterlong")
(princ "\n ppp1   模型绘制多边形视口")
(princ "\n ppp3   布局批量生成视口")
(princ)




masterlong 发表于 2016-10-17 14:09:02

;;选择集转为图元列表
(defun ss2list ( ss / n i elist )
        (setq n (if (= (type ss) 'Pickset) (sslength ss) 0)
                        i n
                        elist '()
        )
        (repeat n
                (setq elist (cons (ssname ss (setq i (1- i))) elist))
        )
)

FireflyButler 发表于 2016-10-18 13:57:42

楼主请问您:如果图框的块是外部参照,要怎么修改呢?

tranney 发表于 2016-10-17 09:55:14

no function definition: SS2LIST

start4444 发表于 2016-8-8 12:21:46

布局不是为了方便打印,核心是为了图层管理和排版

nadaloveluna 发表于 2016-8-8 15:51:30

一直没试成功。。。

masterlong 发表于 2016-8-8 16:40:45

本帖最后由 masterlong 于 2016-8-8 16:44 编辑

这是针对我单位的图框做的程序
你想用自己的图框进行测试
必须对代码做一定的修改

最简单的修改如下
1.
假设你的图框是块
块名是“XXY-A0”、“XXY-A1”、“XXY-A2”等
图框层是“图框”
那么
你需要将55行改为
(setq ss (ssget '((0 . "insert")(2 . "XXY-*"))))
102行改为
(setvar "clayer" "图框")

2.
假设你的图框是PL线
图框层是“图框”
将你的图框PL线和图签一起做成一个临时块
块名就是“QGY_V16_TK-A0”等
不同的块块心统一定为左下或右下角
102行修改同上
执行PPP3后
炸开临时块

masterlong 发表于 2016-8-22 12:44:01

本帖最后由 masterlong 于 2016-8-22 12:47 编辑

明经终于好了

nadaloveluna 发表于 2016-8-26 11:08:19

masterlong 发表于 2016-8-22 12:44 static/image/common/back.gif
明经终于好了

恩。终于回复正常了,我按照楼主的意思再试下。之前可能是图框图层没选好

nadaloveluna 发表于 2016-8-26 11:13:24

图框不支持属性快吗?

nadaloveluna 发表于 2016-8-26 11:26:08

cad附件如下,求解为啥还是不行

本帖最后由 nadaloveluna 于 2016-8-26 11:27 编辑

楼主,我是这样操作的,PPP1绘制矩形视口线,图框名也改成TK-A1,图层也相应改掉了,但是PPP3选择了两个做成块的图框还是不行。。。求解。
修改后的代码

(vl-load-com)
(setq *ent2obj*         vlax-Ename->Vla-Object
    *acad*          (vlax-get-acad-object)
    *doc*          (vla-get-ActiveDocument *acad*)
    *Layouts*      (vla-get-Layouts *doc*)
)

;;模型中绘制多边形视口(不专门绘制,将现有闭合的pl线转成“zzz___多边形视口”图层也可以)
(defun c:ppp1( / p1 p2 p3 p4 templ )
(setvar "cmdecho" 0)
(command "undo" "g")
(command "ucs" "")
(command "layer" "m" "zzz___图框内框线" "p" "n" "zzz___图框内框线" "c" "19" "" "")
(command "layer" "m" "zzz___多边形视口" "p" "n" "zzz___多边形视口" "c" "252" "" "")
(if (and
      (setq p1 (getpoint "绘制多边形视口第1点 : "))
      (setq p2 (getpoint p1 "下一点 : "))
      (null (command "line" "non" p1 "non" p2 ""))
      (setq templ (entlast))
      (setq p3 (getpoint p2 "下一点 : "))
    )
    (progn
      (entdel templ)
      (command "pline" "non" p1 "w" 0 0 "non" p2 "non" p3)
      (while (setq p4 (getpoint p3 "下一点 : "))
      (command "non" (setq p3 p4))
      )
      (command "c")
    )
    (if p2 (entdel templ))
)
(command "undo" "e")
;;(princ "重复执行本程序,继续绘制其它多边形视口")

(princ "\n|\n|\n 模型绘图、布局出图的演示代码   by masterlong")
(princ)
)
;;插入图框,要求图框能完全包含多边形视口
(defun c:ppp2()
;;...略...
(princ)
)
;;布局批量生成视口并配置相应图框
(defun c:ppp3()
(setvar "cmdecho" 0)
(command "undo" "g")
(command "ucs" "")
(command "layer" "m" "zzz___图框内框线" "p" "n" "zzz___图框内框线" "c" "19" "" "")

(princ "按图纸顺序,依次选择图框以生成用于批打印的布局....")
(setq ss (ssget '((0 . "insert")(2 . "TK-A1"))))      ;;单位图框为块,对使用PL围合线作图框的同学,自行修改相应代码
(command "zoom" "e")

;;获取每个图框的块名、角度和比例,生成tkdatlist用于随后生成布局
(setq tkdatlist '())
(foreach tkb (reverse (ss2list ss))
    ;;取图框块名、比例、角度(未校验图框的角度是否0.5PI的整数倍)
    (setq entlist (entget tkb))
    (setq tkname(cdr (assoc2 entlist)))
    (setq tkinssc(cdr (assoc 41 entlist)))
    (setq tkinsang (cdr (assoc 50 entlist)))
   
    ;;取图框两角点————最好是内框————因为是演示代码,取的是外框
    (setq box (entbox tkb))
    (setq tkp1 (carbox))
    (setq tkp2 (cadr box))
   
    ;;绘制非打印图框线,事后可不删,用于绘图时提示用
    (command "rectang" "non" tkp1 "non" tkp2 "change" (entlast) "" "p" "c" 19 "")
   
    ;;是否包含特定的多边形
    ;;两种情况下的tkdatlist构成是不同的
    ;;tkdatlist子表
    ;;有特定多边形时'(图框块名 比例 角度 图框角点1 图框角点2 '(多边形视口块名 '(包围盒角点1 角点2)))
    ;;无特定多边形时'(图框块名 比例 角度 图框角点1 图框角点2 图框线图元名)
    (if (setq vpplss (ssget "w" tkp1 tkp2 '((0 . "LWPOLYLINE")(8 . "zzz___多边形视口"))))
      (progn
      (setq vppl (ssname vpplss 0))      ;;未校验pl是否唯一,是否闭合
      
      ;;vppl做时间块,便于生成视口时调用
      (setq 时间 (getvar "cdate"))
      (setq 时间 (rtos 时间 2 8))
      (setq 组合块名 (strcat "多边形视口块" "___" (substr 时间 14)))
      (command "block" 组合块名 "non" tkp1 vppl "" "oops")
      
      (setq tkdatlist (cons (list tkname tkinssc tkinsang tkp1 tkp2 (list 组合块名 (entbox vppl))) tkdatlist))
      
      )
      (setq tkdatlist (cons (list tkname tkinssc tkinsang tkp1 tkp2 (entlast)) tkdatlist))
    )   
)
(command "erase" ss "")    ;;删除模型中的图框

;;生成专用新布局页面并激活(未测试布局是否已存在)
(setq vpp_vplot (vla-add *Layouts* "v16_布局批打印"))
(vla-put-ActiveLayout *doc* vpp_vplot)
(setvar "clayer" "TK")

;;布局插入图框,建立视口并锁定
(setq popopo '(0 0))
(foreach x tkdatlist
    (command "PSPACE")
   
    ;;插入图框
    (command "insert" (nth 0 x) "non" popopo (nth 1 x) "" (angtos (nth 2 x) 0 9))
    (setq tkb (entlast))
    (setq box (entbox tkb))
    (setq box_w (- (car (cadr box)) (car (car box))))
    (command "move" tkb "" "0,0" (strcat (rtos box_w) "<0"))
    (setq popopo (polar popopo 0 (+ box_w 100000)))
   
    ;;获取插入图框的两角点
    (setq box (entbox tkb))
    (setq tkpp1 (carbox))
    (setq tkpp2 (cadr box))
   
    ;;根据tkdatlist子表第6项,执行不同的流程
    (if (= (type (nth 5 x)) 'ENAME)
      ;;以图框线建立视口并锁定
      ;;特别提醒:布局中建立视口以后,视口是可以拉伸进行调整的
      (progn
      (princ "\n图框线建立视口")
      (command "_mview" "non" tkpp1 "non" tkpp2)
      (command "PSPACE" "zoom" "e")
      (command "_mspace")
      (command "zoom" "w" "non" (nth 3 x) "non" (nth 4 x))
      (command "_mview" "l" "on" "l" "")
      )
      ;;以预设多边形建立视口并锁定,pu对应的时间块
      ;;多边形建立视口的好处是,图面看起来不是那么的满,可以在空白处放一些大样啊、说明啥的
      ;;另外多边形视口很难包括轴号,需要在布局中另外“套”上轴号等
      ;;可以采用模型内多边形的某一角点作基点,复制轴号到布局,再移动到图框内,本演示程序不包含此部分代码————手动操作也不复杂
      (progn
      (princ "\n预设多边形建立视口")
      (command "PSPACE" "zoom" "e")
      (setvar "qaflags" 0)
      (command "insert" (car (nth 5 x)) "non" tkpp1 1 1 0 "explode" (entlast) "purge" "b" (car (nth 5 x)) "n")
      (setq thevppl (entlast))
      (command "_mview" "o" thevppl)
      (command "_mspace")
      ;;下面这句代码很重要,使得模型绘制的多边形和布局的多边形视口完全重合
      (command "zoom" "w" "non" (car (cadr (nth 5 x))) "non" (cadr (cadr (nth 5 x))))
      (command "_mview" "l" "on" thevppl "")
      )
    )
)
(command "PSPACE" "zoom" "e")
(command "undo" "e")

(princ "\n|\n|\n 模型绘图、布局出图的演示代码   by masterlong")
(princ)
)

;;单个物体的最小(正交)包围框---------------------------------这个程序在遇到无法显示的图元时,还是会出错的,比如形。天正图元会不会也不支持,未测试
(defun entbox ( ent / ll ur )
(vla-getboundingbox (*ent2obj* ent) 'll 'ur)
(mapcar 'vlax-safearray->list (list ll ur))
)


(princ "\n|\n|\n 模型绘图、布局出图的演示代码   by masterlong")
(princ "\n ppp1   模型绘制多边形视口")
(princ "\n ppp3   布局批量生成视口")
(princ)

nadaloveluna 发表于 2016-8-26 11:31:39

可否麻烦龙大师看下是什么问题。。。

masterlong 发表于 2016-8-30 22:47:28

论坛一直不能电脑上
等好了以后我会看看是什么情况
页: [1] 2
查看完整版本: 模型绘图、布局出图的演示代码