ezdxf UNDERLAY 实体完全指南:在 DXF 绘图中引用 PDF、DWF 与 DGN 底图
图形学【免费下载链接】ezdxfPython interface to DXF项目地址https://gitcode.com/gh_mirrors/ez/ezdxf点击查看免费下载导读UNDERLAY 实体是 ezdxf 中用于将外部文档PDF、DWF/DWFx、DGN作为底图链接进 DXF 绘图的机制底图文件本身不会被嵌入DXF 文件而始终以独立文件的形式存在。本文基于 dxfentities/underlay.rst 文档结合 实体源码、工厂函数、ObjectsSection 实现 与 官方示例、单元测试系统讲解 UNDERLAY 实体的数据模型、工厂函数、裁剪路径、显示属性对比度/淡出/单色及底层实现原理读完即可在你的 ezdxf 项目中正确创建和管理三种格式的底图引用。UNDERLAY 是什么UNDERLAY 实体DXF 标准中的PDFUNDERLAY、DWFUNDERLAY、DGNUNDERLAY将一个外部底图文件链接到 DXF 文件。其核心设计约束是底图文件不嵌入DXF 文件始终是分离的独立文件移动/分发 DXF 时必须同时携带底图文件(PDF)UNDERLAY实体在行为上类似块引用INSERT同一个底图可以在不同位置、以不同缩放比例和旋转角度被多次引用每次引用都必须挂接一个(PDF)DEFINITION定义实体见 dxfobjects/underlaydef.rst定义实体负责记录底图文件名与显示参数。DXF 标准支持三种底图文件格式PDF、DWF含 DWFx和DGN。底图可以被矩形或多边形路径裁剪裁剪坐标为 2D OCS 坐标单位为绘图单位但不做缩放见 ocs_usage.rst 中 OCS 概念。实体总览与类层次文档给出的类关系如下项目UnderlayPdfUnderlayDwfUnderlayDgnUnderlay父类ezdxf.entities.DXFGraphicUnderlayUnderlayUnderlayDXF 类型内部基类虚拟PDFUNDERLAYDWFUNDERLAYDGNUNDERLAY工厂函数BaseLayout.add_underlay同左同左同左继承属性通用图形 DXF 属性同左同左同左最低 DXF 版本DXF R2000AC1015同左同左同左在源码中Underlay是DXFGraphic的派生虚拟基类PdfUnderlay、DwfUnderlay、DgnUnderlay分别以register_entity注册src/ezdxf/entities/underlay.py 第 346-373 行。MIN_DXF_VERSION_FOR_EXPORT DXF2000表明该实体仅支持 R2000 及以上版本导出graphicsfactory.py 的 add_underlay 会在dxfversion DXF2000时直接抛出DXFVersionError。一个值得注意的细节源码中还注册了PdfReferenceDXFTYPE PDFREFERENCE作为PDFUNDERLAY的同义词——ezdxf 始终创建PDFUNDERLAY实体但能读取某些 CAD 软件写出的PDFREFERENCE类型。UNDERLAY 的 DXF 属性核心数据模型Underlay的所有数据都存放在AcDbUnderlayReference子类标记subclass marker中由 acdb_underlay 定义 描述DXF 属性组码默认值说明dxf.underlay_def_handle340无指向 UNDERLAYDEF 定义实体的硬引用句柄dxf.insert10(0, 0, 0)插入点即底图左下角OCS 坐标dxf.scale_x411x 方向缩放因子float校验非零dxf.scale_y421y 方向缩放因子float校验非零dxf.scale_z431z 方向缩放因子float校验非零dxf.rotation500绕拉伸矢量extrusion逆时针旋转的角度度dxf.extrusion210(0, 0, 1)拉伸矢量可选校验非零向量dxf.flags28010显示属性位标志见下表dxf.contrast281100对比度取值 20–100dxf.fade2820淡出值取值 0–80三个缩放因子在 属性定义 中均带validator.is_not_zerofixerRETURN_DEFAULT即设置为 0 会被拒绝并回退默认值contrast使用is_in_integer_range(20, 101)、fade使用is_in_integer_range(0, 81)做范围校验越界时由fit_into_integer_range钳制回合法区间。flags 位标志文档给出了dxf.flags的位定义常量在 src/ezdxf/lldxf/const.py常量值含义UNDERLAY_CLIPPING1裁剪开/关UNDERLAY_ON2底图显示开/关UNDERLAY_MONOCHROME4单色显示UNDERLAY_ADJUST_FOR_BG8随背景调整默认flags 10即UNDERLAY_ON | UNDERLAY_ADJUST_FOR_BG底图默认显示且自动适应背景。这一点被单元测试明确验证assert underlay.dxf.flags 10test_231_underlay_2.py。便捷属性与关键方法除原始 DXF 属性外Underlay类提供了面向对象编程的读写属性src/ezdxf/entities/underlay.py#L238-L304clippingTrue/False读/写读写位 1onTrue/False读/写读写位 2monochromeTrue/False读/写读写位 4adjust_for_backgroundTrue/False读/写读写位 8scale/scaling(x, y, z)三元组读/写。写入单个 float 时按x y z scale做等比缩放写入元组则分别赋值三个dxf.scale_*boundary_path顶点列表读/写。两个顶点表示矩形裁剪左下角 右上角超过两个顶点表示多边形裁剪路径get_underlay_def()返回关联的 DEFINITION 实体set_underlay_def(def)设置关联定义实体同时更新dxf.underlay_def_handle并向定义实体追加 reactor 句柄set_underlay_defreset_boundary_path()清除裁剪路径并将clipping置False。set_boundary_path(vertices)有一个自动行为传入非空顶点列表时除了保存路径还会自动开启裁剪self.clipping True传入空列表则等效于reset_boundary_path()。裁剪坐标通过组码 11 导出为 2D 点export_boundary_path 使用write_vertex(11, vertex[:2])。创建底图引用add_underlay 工厂函数创建 UNDERLAY 实体的标准入口是布局层的add_underlay方法其签名graphicsfactory.pymsp.add_underlay( underlay_def, # 必需的 UnderlayDefinition 实体 insert(0, 0, 0), # 插入点3D WCS 坐标 scale(1, 1, 1), # 缩放三元组或单一数值等比缩放 rotation0.0, # 绕拉伸轴默认 z 轴旋转角度单位度 dxfattribsNone, # 其他 DXF 属性 ) - Underlay其内部流程是校验 DXF 版本 R2000 抛DXFVersionError→ 把insert转为Vec3写入dxfattribs→ 自动填充underlay_def_handle和rotation→ 调用new_entity(underlay_def.entity_name, ...)按定义实体的格式创建PDFUNDERLAY/DWFUNDERLAY/DGNUNDERLAY→ 设置scaling→ 调用set_underlay_def()建立引用关系。对应地Drawing对象提供add_underlay_def(filename, fmtext, nameNone)src/ezdxf/document.py#L1094-L1115其中fmtpdf、dwf、dgn或ext默认从文件扩展名自动推断name指明显示底图的哪个部分——PDF 为页码、DGN 恒为default、DWF 未明确源码默认给Model。省略时 PDF 默认1第一页、DGN 默认default。UNDERLAYDEF底图定义实体每个 UNDERLAY 引用都依赖于一个定义实体PDFDEFINITION/DWFDEFINITION/DGNDEFINITION它记录dxf.filename组码 1底图文件的相对相对于 DXF 文件或绝对路径dxf.name组码 2要显示的底图部分语义随格式而变PDF 页码 / DGN 恒为default/ DWF 未定。定义实体驻留在OBJECTS 段而非布局空间。ObjectsSection.add_underlay_defsrc/ezdxf/sections/objects.py#L471-L513的实现细节揭示了其存储机制在rootdict中获取/创建名为ACAD_PDFDEFINITIONS或ACAD_DWFDEFINITIONS、ACAD_DGNDEFINITIONS的字典创建PDFDEFINITION等实体owner指向该字典句柄通过next_underlay_key自动生成字典键src/ezdxf/tools/handle.py 的UnderlayKeyGenerator并用underlay_dict[key] underlay_def登记。这也是 underlaydef.rst 强调不要自行实例化对象类始终使用工厂函数的原因——手动构造会绕过 OBJECTS 段字典登记与 reactor 维护。UnderlayDefinition还提供file_format、entity_name、acad_dict_name三个只读属性用于反查所属字典名与对应的 UNDERLAY 类型src/ezdxf/entities/underlay.py#L412-L422。完整可运行示例综合 官方教程 与 示例脚本一个典型的端到端流程如下import ezdxf from ezdxf.math import basic_transformation # 底图需要 DXF R2000 或更高格式 doc ezdxf.new(R2000) pdf_def doc.add_underlay_def(filenameunderlay.pdf, name1) # name 要显示的页码 dwf_def doc.add_underlay_def(filenameunderlay.dwf, nameUnderlay_R2013-Model) dgn_def doc.add_underlay_def(filenameunderlay.dgn, namedefault) msp doc.modelspace() # 同一底图可被多次引用如同 INSERT 一样 msp.add_underlay(pdf_def, insert(0, 0, 0), scale1.0) msp.add_underlay(pdf_def, insert(10, 0, 0), scale0.5, rotation30) # scale 也可传单一数值实现等比缩放 # UNDERLAY 支持 copy() 与 transform() clone pdf_def and msp.add_underlay(pdf_def, insert(0, 0, 0), scale1.0) clone clone.copy() clone.transform(basic_transformation(move(20, 0), scale(0.25, 0.25, 0.25), z_rotation-30)) msp.add_entity(clone) # 查询现有定义UNDERLAYDEF 位于 OBJECTS 段 pdf_defs doc.objects.query(PDFDEFINITION) doc.saveas(dxf_with_underlay.dxf) # 别忘了把底图文件复制到 DXF 同级目录否则 CAD 应用找不到底图注意示例脚本开头明确警告——UNDERLAY 对象在不同 CAD 应用之间不能保证可靠工作非必要不要使用 UNDERLAYexamples/entities/underlay.py。DWF 底图的name取值难以从外部得知这增加了跨 CAD 兼容的难度。裁剪示例# 矩形裁剪两个顶点 左下角 右上角 underlay.set_boundary_path([(0, 0), (640, 180)]) # 多边形裁剪三个及以上顶点 underlay.set_boundary_path([(0, 0), (640, 180), (320, 360)]) assert underlay.clipping is True # 设置路径后自动开启裁剪 underlay.reset_boundary_path() # 移除裁剪路径并关闭裁剪上述行为与测试 test_set_boundary_path 完全一致三顶点三角形路径写入后clipping 1boundary_path原样保留。底层实现与边界行为加载与导出读取时load_dxf_attribs 定位AcDbUnderlayReference子类标记先用load_boundary_path把组码 11 的顶点抽取为boundary_path其余标签照常解析再快速装载其余属性若裁剪顶点少于 2 个则自动reset_boundary_path()。缺少该子类标记会抛出DXFStructureError。导出时 export_entity 按固定顺序写出 340/10/41/42/43/50/210/280/281/282 与组码 11 裁剪顶点。测试 test_write_dxf 用TagCollector.dxftags验证了读写往返的字节级一致性。引用关系维护reactorpost_load_hook通过underlay_def_handle从doc.entitydb解析出定义实体存入self._underlay_defpost_bind_hook在实体绑定文档时向定义实体追加 reactor 句柄destroy()时反向移除src/ezdxf/entities/underlay.py#L157-L169 与 306-313 行。测试验证了copy()出的克隆与原件共享同一个定义实体且原件的句柄与克隆句柄都出现在定义实体的reactors列表中test_231_underlay_2.py。变换transformUnderlay.transform(m)复用与 INSERT 相同的InsertCoordinateSystem机制src/ezdxf/entities/underlay.py#L315-L343从 insert/scale/rotation/extrusion 构造源坐标系用矩阵m变换到目标坐标系再回写四个属性。由于 UNDERLAY 无法表达非正交目标坐标系此时会抛出InsertTransformationError提示信息明确指出该限制。测试 test_transform_underlay 确认其变换逻辑与 INSERT 走同一底层函数并验证了translate(1, 2, 3)后insert变为(1, 2, 3)。外部参照xref支持Underlay实现了register_resources/map_resources/map_underlay_defsrc/ezdxf/entities/underlay.py#L196-L228因此底图引用可作为外部参照资源被复制和映射复制定义实体时会检查目标文档rootdict中是否已有同名字典项没有则调用doc.objects.next_underlay_key生成新键并take_ownership保证定义实体在新文档中登记到正确的ACAD_*DEFINITIONS字典。兼容性注意事项版本UNDERLAY 要求 DXF R2000AC1015及以上旧版本会直接抛异常文件分离DXF 只记录文件名路径不包含底图内容分发时必须同步底图文件示例脚本末尾用shutil.copy演示了这一步跨 CAD 可靠性示例与 ezdxf 文档均提示 UNDERLAY 在不同 CAD 应用间的兼容性不稳定尤其是 DWF 的name参数语义不明确在实际项目中应充分验证目标 CAD 的读取行为坐标语义裁剪路径是 2D OCS 坐标、不带缩放的绘图单位插入点同样是 OCS 坐标而add_underlay的insert参数按 WCS 处理两者需区分。赞分享图形学【免费下载链接】ezdxfPython interface to DXF项目地址https://gitcode.com/gh_mirrors/ez/ezdxf点击查看免费下载相关推荐ezdxf UnderlayDefinition 详解PDF/DWF/DGN 底图定义实体的创建、属性与底层机制ezdxf UnderlayDefinition 详解PDF/DWF/DGN 底图定义实体的创建、属性与底层机制 UnderlayDefinition DX图形学ezdxf HPGL/2 转换 Add-on 实战指南将 PLT 绘图文件转换为 DXF、SVG、PDF 与位图ezdxf HPGL/2 转换 Add on 实战指南将 PLT 绘图文件转换为 DXF、SVG、PDF 与位图 HPGL/2Hewlett Packard图形学ezdxf 中 SHAPE 实体详解外部 SHX 形状引用、DXF 属性与底层实现ezdxf 中 SHAPE 实体详解外部 SHX 形状引用、DXF 属性与底层实现 本文基于 ezdxf 官方文档中的 SHAPE 实体章节 shape.r图形学创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考