图形学【免费下载链接】ezdxfPython interface to DXF项目地址https://gitcode.com/gh_mirrors/ez/ezdxf点击查看免费下载导读extents范围与limits界限是 CAD 布局Layout中最常被 ZOOM、LIMITS 等命令引用的两种边界概念前者描述绘图对象实际占据的区域后者定义绘图区内不可见的矩形边界。本文以 ezdxf 官方文档《Layout Extents and Limits》为主体结合 layout.py、document.py、headervars.py 与 zoom.py 的源码系统讲解这 8 个头变量$EXTMIN、$EXTMAX、$LIMMIN、$LIMMAX、$PEXTMIN、$PEXTMAX、$PLIMMIN、$PLIMMAX的存储位置、默认值、读写方式与同步机制并给出计算模型空间 extents、设置初始视口的完整可运行示例。Extents 与 Limits两种边界概念Extents范围布局的extents范围由该布局内所有 DXF 实体的最大包络决定。AutoCAD 命令行中的ZOOM extents会把当前视口设置为当前选中布局的 extents 区域。下面是一个处于任意缩放状态的图纸空间布局执行ZOOM extents之后视口被缩放到恰好容纳布局内全部对象Limits界限limits界限则在绘图区设置一个不可见的矩形边界它可以限制网格grid的显示范围也可以限制鼠标点击或输入点坐标的位置。图纸空间布局的默认 limits 由纸张尺寸决定。上图中同一个布局在执行ZOOM all命令后视口被设置为同时容纳 extents 与 limits 的更大区域对比三张图可以直观理解ZOOM extents只看对象包络而ZOOM all还会把布局的 limits 边界纳入视野。这两个命令的完整行为定义可参考 AutoCAD 官方对ZOOM与LIMITS命令的说明。存储位置8 个头变量与 Layout 属性在 DXF 文档中extents 与 limits 同时存在于两处HEADER 节的头变量和Layout 对象的 DXF 属性。模型空间Model的 extents 与 limits模型空间标签页名为 Model的 extents 存储在头变量$EXTMIN与$EXTMAX中其默认值为头变量默认值含义$EXTMIN(1e20, 1e20, 1e20)最小范围点$EXTMAX(-1e20, -1e20, -1e20)最大范围点这两个默认值显然不能描述真实边界它们只是未设置的占位符。在 headervars.py 中可以看到二者均以Point3D工厂构造、使用组码code10支持范围从DXF12到DXF2018。模型空间的 limits 存储在$LIMMIN与$LIMMAX中默认值为(0, 0)与(420, 297)——即 ezdxf 默认的 A4 横向纸张尺寸以绘图单位计。从 headervars.py 的定义看这两个变量使用Point2D工厂构造limits 是二维概念默认$LIMMAX (420.0, 297.0)。当前激活图纸空间布局的 extents 与 limits除模型空间外当前激活的图纸空间布局即最后一个被激活的 paperspace 标签页的 extents 与 limits 分别存储在头变量对应含义$PEXTMIN/$PEXTMAX当前激活图纸空间布局的 extentsPoint3D默认±1e20$PLIMMIN/$PLIMMAX当前激活图纸空间布局的 limitsPoint2D默认(0,0)/(420,297)这些变量在 headervars.py 中的定义与模型空间的对应变量结构一致code10、mindxfDXF12、maxdxfDXF2018并带有较高的写入优先级priority 18200–18500。每个图纸空间布局自己的存储每个paperspace 布局都有自己独立的一套值存储在该布局对应的Layout对象属性中Layout.dxf.extmin/Layout.dxf.extmaxLayout.dxf.limmin/Layout.dxf.limmax也就是说头变量$PEXTMIN、$PEXTMAX、$PLIMMIN、$PLIMMAX只反映当前激活的那个图纸空间布局而布局自身的属性则与布局一一对应、互不干扰。读取存储值读取这些值有两种途径直接读取头变量或通过Layout对象读取。通过 HEADER 节读取import ezdxf doc ezdxf.readfile(your.dxf) header doc.header extmin header.get($EXTMIN) # (x, y, z) 三元组 extmax header.get($EXTMAX) limmin header.get($LIMMIN) # (x, y) 二元组 limmax header.get($LIMMAX) pextmin header.get($PEXTMIN) pextmax header.get($PEXTMAX) plimmin header.get($PLIMMIN) plimmax header.get($PLIMMAX)header.get()的第二个参数是默认值例如header.get($PLIMMIN, (0, 0))可避免旧版文档缺少该变量时抛异常。通过 Layout 对象读取msp doc.modelspace() print(msp.dxf.extmin, msp.dxf.extmax) # 模型空间 extents print(msp.dxf.limmin, msp.dxf.limmax) # 模型空间 limits psp doc.paperspace(Layout1) # 或 doc.active_layout() print(psp.dxf.extmin, psp.dxf.extmax) # 该图纸空间布局的 extents print(psp.dxf.limmin, psp.dxf.limmax) # 该图纸空间布局的 limits需要说明的是头变量是 Layout 属性的副本两者并非实时同步——同步发生在保存文档时详见下一节这也是创建后直接改 Layout 属性即可生效这一设计能成立的原因。设置 Extents 和 Limits保存时自动同步头变量v0.16 起的设计从 ezdxfv0.16起你只需设置Layout对象的extents与limits属性即Layout.dxf.extmin、Layout.dxf.extmax、Layout.dxf.limmin、Layout.dxf.limmax头变量会在文档保存时自动同步无需手动修改 HEADER 节。源码中的同步机制同步逻辑位于 document.py 的update_all()方法中它由保存流程调用依次执行update_extents()与update_limits()def update_extents(self): msp self.modelspace() # many applications not maintain these values extmin msp.dxf.extmin extmax msp.dxf.extmax if bool(extmin) and bool(extmax): self.header[$EXTMIN] extmin self.header[$EXTMAX] extmax active_layout self.active_layout() self.header[$PEXTMIN] active_layout.dxf.extmin self.header[$PEXTMAX] active_layout.dxf.extmax def update_limits(self): msp self.modelspace() self.header[$LIMMIN] msp.dxf.limmin self.header[$LIMMAX] msp.dxf.limmax active_layout self.active_layout() self.header[$PLIMMIN] active_layout.dxf.limmin self.header[$PLIMMAX] active_layout.dxf.limmax从源码document.py可以看出两个关键行为$EXTMIN/$EXTMAX仅在bool(extmin) and bool(extmax)成立即已被真实赋值时才写入——因为默认的±1e20是无效占位值很多 CAD 应用并不维护这两个变量$PEXTMIN等四个图纸空间变量始终从active_layout()当前激活布局同步而每个布局自身的属性则不会丢失激活布局切换后头变量会随之变化。手动设置属性直接赋值即可msp doc.modelspace() msp.dxf.extmin (0.0, 0.0, 0.0) msp.dxf.extmax (100.0, 80.0, 0.0) msp.dxf.limmin (0.0, 0.0) msp.dxf.limmax (420.0, 297.0) doc.saveas(setup.dxf) # 保存时头变量自动同步一个重要的前提extents 不会被自动计算ezdxf不会自动计算布局的 extents——对大型文档而言实时计算可能非常耗时而正确的 extents 值并非生成合法 DXF 文档的必需条件。因此$EXTMIN/$EXTMAX保持±1e20占位值是完全合法的。如果你需要准确的 extents 值请使用下一节的ezdxf.bbox模块主动计算。便捷方法reset_extents / reset_limits / reset_paper_limitslayout.py 提供了三个便捷方法用于重置这些属性Layout.reset_extents()def reset_extents( self, extmin(1e20, 1e20, 1e20), extmax(-1e20, -1e20, -1e20) ) - None将 extents 重置为给定值或 AutoCAD 默认值即±1e20占位值实现见 layout.py。Layout.reset_limits()def reset_limits(self, limminNone, limmaxNone) - None将 limits 重置为给定值或默认值limmin默认为(0, 0)limmax默认为(dxf.paper_width, dxf.paper_height)——即图纸尺寸见 layout.py。Paperspace.reset_paper_limits() 与 get_paper_limits()Paperspace类还有额外的reset_paper_limits()方法它从纸张设置推导默认 limitslayout.py根据plot_paper_units0 表示英寸、1 表示毫米换算单位把左边距与打印原点偏移累加为shift_x最终得到dxf.limmin (-shift_x, -shift_y) dxf.limmax (paper_width - shift_x, paper_height - shift_y)即 limits 描述的是相对打印原点的纸张边界。配套的get_paper_limits()layout.py返回(Vec2(x1, y1), Vec2(x2, y2))左下角与右上角各一个点。Paperspace.page_setup()layout.py在设置纸张、页边距、缩放比例与旋转后也会依次调用reset_paper_limits()、reset_extents()与reset_viewports()来重建一套一致的布局边界。实战如何计算并写入模型空间 extents自 v0.16 起ezdxf 提供了 bbox.py 模块用于计算 DXF 实体的包围盒。核心函数bbox.extents(entities)会递归分解实体、逐一计算并合并其包围盒import ezdxf from ezdxf import bbox doc ezdxf.readfile(your.dxf) msp doc.modelspace() extents bbox.extents(msp) # 返回 ezdxf.math.BoundingBox 对象返回的extents是一个BoundingBox对象其extmin、extmax属性即最小/最大角点。完整的写入流程import ezdxf from ezdxf import bbox doc ezdxf.readfile(your.dxf) msp doc.modelspace() box bbox.extents(msp) if box.has_data: # 布局内至少有一个实体 msp.dxf.extmin box.extmin msp.dxf.extmax box.extmax doc.saveas(with_extents.dxf) # 保存时同步到 $EXTMIN/$EXTMAX几点说明详见 bbox.py 的文档字符串bbox.extents()会把 INSERT块引用展开为其中子实体的包围盒fastTrue时贝塞尔曲线的计算基于其控制点可能返回略大的包围盒但速度更快该模块对某些复杂实体如多重引线、网格等存在已知局限性请以模块文档为准。实战用 ZOOM 命令设置初始视口除了写入头变量还可以通过 zoom.py 模块直接设置布局的初始视口效果等同于在 CAD 软件中执行 ZOOM 命令。该模块提供四个函数函数行为zoom.extents(layout)将激活视口重置为布局内所有实体的 extents可用factor放大视口zoom.objects(layout, entities)将视口重置为给定实体的 extents仅考虑属于该布局的实体zoom.window(layout, p1, p2)将视口重置为矩形窗口左下角p1、右上角p2zoom.center(layout, point, size)将视口中心设为point宽高由size定义例如把模型空间的初始视图设置为全部实体的 extentsimport ezdxf from ezdxf import zoom doc ezdxf.readfile(your.dxf) msp doc.modelspace() zoom.extents(msp)或者只针对部分实体如所有 LINE设置视口lines msp.query(LINE) zoom.objects(msp, lines)其实现逻辑zoom.py是先调用bbox.extents(entities, fastTrue)计算包围盒再通过center()将主视口配置替换为单一窗口。注意zoom.extents()设置的是VPORT 视口配置与头变量$EXTMIN/$EXTMAX是两回事前者决定 CAD 打开文件时的显示区域后者是文档元数据。另一种设置初始视口的方式是直接调用doc.set_modelspace_vport(height, center)通过dxf.center与dxf.height属性指定模型空间中显示区域的中心与高度doc.set_modelspace_vport(height10, center(10, 10))小结围绕 ezdxf 的布局边界机制本文核心结论可归纳为概念区分extents是对象实际包络对应ZOOM extentslimits是不可见矩形边界对应ZOOM all/LIMITS命令存储结构模型空间对应$EXTMIN/$EXTMAX/$LIMMIN/$LIMMAX当前激活图纸空间布局对应$PEXTMIN/$PEXTMAX/$PLIMMIN/$PLIMMAX每个布局自身还有独立的Layout.dxf.extmin/extmax/limmin/limmax属性同步机制v0.16 起只需设置 Layout 属性保存时 document.py 的update_all()会把它们同步进 HEADER 节$EXTMIN/$EXTMAX仅在有真实数据时才写入主动计算ezdxf 不自动计算 extents需要时用ezdxf.bbox.extents()计算并写入Layout.dxf.extmin/extmax视口设置需要控制 CAD 打开文件后的显示区域用ezdxf.zoom模块extents/objects/window/center或doc.set_modelspace_vport()。这套机制让你既能生成合规的 DXF 文件又能在需要时精确控制布局边界与初始视图是 ezdxf 布局管理与打印前准备的关键一环。赞分享图形学【免费下载链接】ezdxfPython interface to DXF项目地址https://gitcode.com/gh_mirrors/ez/ezdxf点击查看免费下载相关推荐深入解析 G6 蛇形布局Snake Layout原理、配置与实战深入解析 G6 蛇形布局Snake Layout原理、配置与实战 蛇形布局Snake Layout是 G6 中一种面向 长链结构 的专用布局算法它将数据可视化前端图表库Angular CDK Layout 响应式布局指南BreakpointObserver 与 MediaMatcher 深入解析Angular CDK Layout 响应式布局指南BreakpointObserver 与 MediaMatcher 深入解析 angular/cdk/l前端UI组件设计系统QEMU Sparc32 键盘布局配置指南escc.chnA-sunkbd-layout 属性详解QEMU Sparc32 键盘布局配置指南escc.chnA sunkbd layout 属性详解 本指南围绕 QEMU 对 Sun 体系Sparc32/S虚拟化硬件仿真上一篇突破量化精度瓶颈Brevitas中QuantTensor与QuantConv2d深度优化指南下一篇终极指南如何为speak.js项目添加或改进语言支持创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考