明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 24086|回复: 114

[源码] 批选图块后自动布局

  [复制链接]
发表于 2017-8-15 21:06:14 | 显示全部楼层 |阅读模式
本帖最后由 荒野孤行 于 2017-8-15 21:10 编辑

一份CAD图中包含有多份图档需打印,将每份图档布局后设置打印窗口后运用“发布”功能为PDF文件,将PDF档发给工厂去自行打印,这样方便你我他。
看了秋枫早期公布的批量打印源码,功能挺多的,看着代码犯晕,由于只需要布局功能,故依其源码借鉴出部分功能的实现。

关于选图块图框生成布局的功能,考虑的思路如下:
(1)通过viewsize获取视窗区的高度
(2)通过screensize获取屏幕像素的宽度/高度尺寸
(3)通过viewctr获取视窗区的中心坐标点
(4)计算得出视窗区的左下角、右上角坐标点
(5)批量图块类的图框
(6)获取模型空间的打印设备名称、图纸尺寸、打印样式
(7)新建布局并清空视口
(8)根据前面(1)~(4)步得到的信息设置视口 ,导致布局里面的图框大小&位置与模型里面的有微小偏差 ←这里还是有点问题,在模型空间中所有对象布满后其实在上/下左/右是有空余的,需要知道空余边框宽度是多少,请大神帮忙
(9)计算图框的左下角、右上角坐标点,将打印范围→窗口里面的坐标点设置为此
(10)循环次数...

其它待优化:图块图框的排序

;;;***批量布局 程序开始***
(defun c:bpt ()
  (setvar "osmode" 15359)
  (setvar "cmdecho" 0)
  (princ "\n★批量布局功能的调用命令:bpt;制作者:荒野孤行")
  (if (< (atof (getvar "acadver")) 15.0)
    (progn
      (alert
        "此程序为AutoCAD 2000以上的版本设计。不支持AutoCAD R14及以下版本!"
      )
      (exit)
    )
  )
  (if (= (getvar "tilemode") 0)
    (setvar "tilemode" 1)
  )
  (vl-load-com)
  (setq        acadobj              (vlax-get-acad-object)
        doc              (vla-get-activedocument acadobj)
        active_layout (vla-get-activelayout doc) ;获取当前布局名称
        layout_lst    (vla-get-layouts doc) ;获取所有布局名称
        model_layout  (vla-item layout_lst "Model") ;模型空间
  )
(vla-refreshplotdeviceinfo active_layout) ;刷新打印设备信息
  (setq        PlotterLabel
         (vla-get-configname active_layout)
  )                                        ;获取当前打印设备名称
  (if (vl-catch-all-error-p PlotterLabel)
    (progn
      (vl-catch-all-error-message PlotterLabel)
      (princ
        "\n请在“打印机/绘图仪→名称”中设置打印设备后,再执行此程序!"
      )
      (alert
        "\n请在“打印机/绘图仪→名称”中设置打印设备后,再执行此程序!"
      )
      (exit)
    )
  )
  (setq        PaperLabel
         (vla-GetLocaleMediaName
           active_layout
           (vla-get-CanonicalMediaName active_layout)
         )
  )                                        ;获取当前纸张设定选型
  (setq        PlotStyleLabel
         (vla-get-stylesheet active_layout)
  )                                        ;获取当前打印样式
  (vl-cmdf "_.zoom" "_all")
  (setq h (/ (getvar "viewsize") 2.0))        ;获取视窗区的高度
  (setq sc (getvar "screensize"))        ;获取屏幕的宽度/高度尺寸
  (setq w (* h (/ (car sc) (cadr sc))))        ; 计算得出视窗区的宽度
  (setq vpctr (getvar "viewctr"))        ; 获取视窗区的中心坐标点
  (setq vpmin (mapcar '- vpctr (list w h)))
                                        ;计算得出视窗区的左下角坐标点
  (setq vpmax (mapcar '+ vpctr (list w h)))
                                        ;计算得出视窗区的右上角坐标点
  (princ "\n请选择图块:")
  (if (not (setq ssblock (ssget '((0 . "INSERT")))))
    (progn (princ "\n提示:未选中图块,程序退出\n") (exit))
  )
  (setq i 0)
  (repeat (sslength ssblock)
    (setq entnam (ssname ssblock i))
    (setq obj (vlax-ename->vla-object entnam))
    (vla-getboundingbox
      obj
      'leftdown
      'rightup
    )                                        ;获取图块的包围盒大小
    (setq ptlst (mapcar 'vlax-safearray->list (list leftdown rightup)))
    (setq x1  (caar ptlst)
          y1  (cadar ptlst)
          x2  (caadr ptlst)
          y2  (cadadr ptlst)
          pt1 (list x1 y1)
          pt2 (list x2 y2)
    )                                        ;转换后的图块包围盒左下角和右上角坐标点
    (if        (< (abs (- x1 x2)) (abs (- y1 y2)))
      (setq upsidedown T)
      (setq upsidedown nil)
    )                                        ;判断横向或竖向
    (setq laynewnam (strcat "wdy_" (itoa (+ 1 i))))
    (vl-cmdf "_.layout"
             "_new"
             laynewnam
    )
    (setvar "ctab" laynewnam)                ;将布局设为当前
    (vl-cmdf "_.ERASE" "_all" "")        ;删除布局内所有对象
    (vl-cmdf "_.MVIEW" vpmin vpmax)        ;新建视口
    (layoutset)
    (vl-cmdf "_.Zoom" "_all")
    (setq i (+ i 1))
  )
  (setvar "tilemode" 1)
  (princ)
)
;;布局设置
(defun layoutset ()
  (setq        acadobj              (vlax-get-acad-object)
        active_doc    (vla-get-activedocument acadobj)
        active_layout (vla-get-activelayout active_doc)
  )                                        ;获取当前布局名称
  (vla-put-configname active_layout PlotterLabel) ;设置:打印设备名称
  (vla-put-stylesheet active_layout PlotStyleLabel) ;设置:打印样式
  (vla-put-showplotstyles active_layout :vlax-false)
                                        ;设置:不按打印样式
  (setq target (getvar "target"))
  (vla-SetWindowToPlot
    active_layout
    (2DPoint (mapcar '- (car ptlst) target))
    (2DPoint (mapcar '- (cadr ptlst) target))
  )                                        ;设置打印窗口,需放在vla-put-plotType前步执行,否则会出错
  (vla-put-PlotType active_layout acWindow) ;打印范围-设置为窗口
  (vla-put-CenterPlot active_layout :vlax-true)
                                        ;打印偏移-设置为:居中打印
  (vla-put-standardscale active_layout acScaleToFit)
                                        ;打印比例-设置为:布满图纸
  (vla-put-paperunits active_layout acMilliMeters) ;设置图纸单位
  (vla-put-plotrotation
    active_layout
    (if        upsidedown
      ac270degrees
      ac90degrees
    )
  )                                        ;设置横向或竖向
)
;;2维点列程
(defun 2DPoint (pt)
  (vlax-make-variant
    (vlax-safearray-fill
      (vlax-make-safearray vlax-vbdouble '(0 . 1))
      (list (car pt) (cadr pt))
    )
  )
)
;;;***批量布局 程序结束***


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

点评

这样用户只需要写个批量创建views的程序就方便很多了。  发表于 2017-8-21 09:14
这么做,不会有任何误差。 还有另外一种方法:对每个图框块创建named view ,然后在 layout 的vp中restore view, 这么做代码更加简单。 实际最新的测试版中已经新增直接插入 named view的功能了。  发表于 2017-8-21 09:13
这么做,不会有任何误差。 还有另外一种方法:对每个图框块创建named view ,然后在 layout 的vp中restore view, 这么做代码更加简单。 实际最新的测试版中已经新增直接插入 named view的功能了。  发表于 2017-8-21 09:13
不要用 zoom all ,在创建 layout, viewport后 ,激活model view,用 zoom center,center 就是图框块的中心点(可能需要trans),viewheight 就是图框块的短边长度。  发表于 2017-8-21 09:10

评分

参与人数 1明经币 +2 收起 理由
xyp1964 + 2 赞一个!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下

本帖被以下淘专辑推荐:

 楼主| 发表于 2017-12-30 09:53:30 | 显示全部楼层
w245272914 发表于 2017-12-26 15:14
荒野孤行。   荒哥程序使用,怎么出现错误啊,需要什么已知条件吗?能否指点下,3Q

有在选项中添加Express工具(AutoCAD自带的,安装时需勾选)吗?
因为像vl-,vla-开头的函数是调用了c++、vb开发的集成函数的。
发表于 2017-8-21 09:03:54 | 显示全部楼层
获得图框块的矩形对角线两个角点坐标后,按viewsize这些参数计算出来的 viewport的尺寸应该是对的不会有误差。
需要更多处理的是非平行于当前UCS的矩形图框块的正确角点坐标并转换到 layout的vp中。
还有layout的pagesetup最好也设置好。
发表于 2017-8-16 12:48:43 | 显示全部楼层
楼主提到的瑕疵是不是说
模型里图框与布局中的视口没有完全重合?

如果是的话
假设图框是水平或垂直摆放的
获取图框包围框
在布局中建立同样尺寸的视口
转布局进入视口以后
zoom ‘w p1 p3
再锁定比例
这样图框与视口完全重合
发表于 2022-9-13 12:44:02 | 显示全部楼层

老师这个可以做成吗?

本帖最后由 网络工作者 于 2022-9-27 21:19 编辑

您好,老师,麻烦您看下这种情况能不能实现,根据模型里矩形框线批量自动套图框根据模形里的选择顺序批量生成在布局1里面。麻烦大神赐教。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2022-4-19 07:50:50 | 显示全部楼层
好程序! 非常感謝大師分享!
发表于 2021-11-9 15:56:31 | 显示全部楼层
留言一下 ,以后会用到
发表于 2021-9-10 14:16:13 | 显示全部楼层
用不了用不了
发表于 2020-3-7 00:12:39 来自手机 | 显示全部楼层
看着挺好的,有空试试
发表于 2019-11-19 21:35:55 | 显示全部楼层
不错,不过VL函数的都不能加载  不知道为啥
发表于 2018-1-22 16:44:03 | 显示全部楼层
留言一下 ,以后会用到
发表于 2018-1-14 13:13:02 | 显示全部楼层
荒野孤行 发表于 2017-12-30 09:53
有在选项中添加Express工具(AutoCAD自带的,安装时需勾选)吗?
因为像vl-,vla-开头的函数是调用了c++ ...

如何将批量布局后的图 放在一个布局图集里面
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-12-23 05:02 , Processed in 0.205300 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表