自定义图元在保存后于其他CAD中打开显示空白,核心原因是自定义图元的定义(类、代理信息)未在目标CAD环境中注册或加载。这本质上是CAD的代理图形(Proxy Graphics)与自定义对象(Custom Object)的持久化与重建问题。
核心原因与解决方案
| 问题环节 | 具体原因 | 解决方案 |
|---|---|---|
| 1. 图元定义缺失 | 目标CAD未安装或加载包含自定义图元类的.NET程序集(DLL)。 | 将二次开发程序集部署到目标CAD的搜索路径,并使用NETLOAD命令手动加载,或通过注册表实现自动加载。 |
| 2. 代理信息未保存/读取 | 自定义类未正确实现序列化接口,或DwgFil/Dxf文件未完整保存代理数据。 | 确保自定义实体类继承自正确的基类(如Entity),并正确实现ISerializable接口或重写序列化方法。 |
| 3. 图形代理(Proxy)机制 | CAD为未知图元创建“代理图形”,若代理图形绘制代码(WorldDraw)未正确实现或代理数据丢失,则显示空白。 | 在自定义实体中正确重写WorldDraw方法,确保即使作为代理,也能提供基本的图形表示。同时,在目标环境中提供“完全代理”(即加载程序集)以还原完整对象。 |
关键代码实现要点
以下以AutoCAD .NET API为例,说明确保自定义图元可跨环境正确保存和加载的关键代码结构。
1. 基础自定义实体类框架
确保类继承自Entity,并正确实现序列化构造函数和代理标志。
using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; using System; [Serializable] public class MyCustomEntity : Entity { // 自定义数据字段 private Point3d _center; private double _radius; // 默认构造函数(必需) public MyCustomEntity() { } // 序列化构造函数(必需) protected MyCustomEntity(SerializationInfo info, StreamingContext context) : base(info, context) { // 反序列化自定义字段 _center = (Point3d)info.GetValue("Center", typeof(Point3d)); _radius = (double)info.GetValue("Radius", typeof(double)); } // 重写GetObjectData以序列化自定义字段 public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("Center", _center); info.AddValue("Radius", _radius); } // 关键:设置代理图形标志 public override SubentityType SubentityType { get { return SubentityType.ProxyEntity; } } }2. 实现WorldDraw方法(确保代理有图形)
即使自定义图元在未加载程序集的CAD中作为代理存在,WorldDraw方法也应提供基本的图形表示。
public override bool WorldDraw(WorldDraw wd) { if (wd.Geometry != null) { // 绘制一个圆作为代理图形示例 wd.Geometry.Circle(_center, _radius, Vector3d.ZAxis); // 可以添加更多图形,如文本标签等 } return true; }3. 注册自定义类与代理信息(关键步骤)
在程序集初始化时,必须向CAD运行时注册自定义类,使其能被识别和代理。
public class MyCommands { [CommandMethod("REGISTERMYENTITY")] public static void RegisterMyEntity() { // 获取当前数据库的代理对象字典 DBDictionary proxyDict = (DBDictionary)Application.DocumentManager.MdiActiveDocument .Database.ProxyDictionary.GetObject(OpenMode.ForWrite); // 创建或更新代理记录 using (ProxyInfo proxyInfo = new ProxyInfo()) { proxyInfo.Description = "My Custom Entity"; proxyInfo.OriginalClassName = "MyNamespace.MyCustomEntity"; proxyInfo.ProxyFlags = ProxyFlags.None; // 或根据需要设置 // 将代理信息存入字典 proxyDict.SetAt("MyApp_MyCustomEntity", proxyInfo); } proxyDict.DowngradeOpen(); } }部署与加载流程
为确保文件在其他CAD中正常打开,必须遵循以下流程:
- 程序集强命名与安装:为二次开发程序集进行强命名,并将其安装到目标计算机的全局程序集缓存(GAC)或AutoCAD的专用搜索目录中。
- 自动加载配置:通过修改注册表,在
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\Rxx.x\xxx\Applications下添加键值,使AutoCAD启动时自动加载你的程序集。 - 文件保存:在源CAD中保存包含自定义图元的DWG文件时,确保“保存代理图形”选项已启用(在
OPTIONS->打开和保存->ObjectARX应用程序中设置)。 - 目标环境打开:在目标CAD中打开文件时,若程序集已正确部署,自定义图元将完整还原;若未部署,将显示由
WorldDraw绘制的代理图形,而非空白。
针对开源CAD(如LitCAD)的特别说明
若你的自定义图元是针对如LitCAD这类基于C#开发的开源CAD软件,其原理类似但实现细节不同。你需要确保:
*自定义图元类遵循LitCAD的特定基类和接口(如Entity基类)。
- 图元数据能正确序列化到LitCAD的
.litcad文件格式(基于XML)中。 - 目标LitCAD应用程序已加载包含你自定义图元类的模块或插件。由于其模块化架构,可能需要将你的程序集放置在其指定的模块目录下。
总结:解决空白问题的根本在于,确保自定义图元的定义(程序集)和代理图形数据能随文件一起在目标CAD环境中被正确找到、加载和重建。
参考来源
- 免费开源CAD软件LitCAD:3分钟掌握专业二维绘图设计
- LitCAD:免费开源CAD软件,15分钟掌握专业二维绘图技巧
- 如何用C开发的开源CAD软件LitCAD,15分钟开启你的专业绘图之旅?
- 零成本掌握专业CAD绘图:开源LitCAD完全使用秘籍
- 终极指南:如何用LitCAD在30分钟内掌握专业2D CAD绘图技巧