一.简述
CAD数据库对象可以灵活添加一定数量的自定义数据,供开发者使用,这些数据由开发者自己进行解释 ,CAD不管其含义,但要遵循一定的组码规则,这些数据被称为扩展数据XData。扩展数据以吸附物的形式吸附在实体上。
1.可以通过实体DBObject类及其派生类的XData属性获取或设置扩展数据,实体的扩展数据由应用程序创建。
2.实体的扩展数据可以是一组或多组,每一组都以一个互不相同的注册应用程序名开头。
简而盖之:
XData数据形式类似字典Dictionary,但是此字典的key有一个,value可以是多个(一组或多组),这里的key必须按照DxfCode组码规则来,value也必须根据选定的组码选用约定好的数据形式
DXF 组码值 |
扩展数据内容 |
1000~1009 |
字符串 (最多不超过 255 个字符) |
1001 |
Xdata 的应用程序名 |
1002 |
Xdata 的控制字符串 |
1003 |
图层名 |
1004 |
二进制数据 |
1005 |
数据库对象句柄 |
1010~1059 |
浮点数 |
1010,1020,1030 |
三维点(x, y , z) |
1011,1021,1031 |
三维空间位置 |
1012,1022,1032 |
三维空间距离 |
1013,1023,1033 |
三维空间方向 |
1040 |
Xdata 中的浮点数 |
1041 |
Xdata 中的距离值 |
1042 |
Xdata 中的比例系数 |
1060~1070 |
16 位整数 |
1071 |
32 位整数 |
二.步骤
1.注册应用程序
什么是应用程序---->说白了就相当于你扩展数据的一个分类,扩展数据前,必须明确你扩展的数据属于哪一个应用程序。
2.注册应用程序
应用程序首先应要注册到CADRegAppTable表中,在给图元扩展数据的时候,首先明确扩展数据对应的应用程序是否已经注册,没有注册的则必须注册。CAD将注册的应用程序名保存于数据库中的RegAppTable中。使用之前应检测应用程序名是否已经注册,如果没有注册,则需要创建一个RegAppTableRecord表记录。
3.数据对
结果缓存即 Autodesk.AutoCAD.DatabaseServices.ResultBuffer 类型,使用 ResultBuffer 对象时需要提供一个数据对,每个数据对包含一个数据类型描述和一个值,这些数据对Autodesk.AutoCAD.DatabaseServices.TypedValue 类的实例。
TypedValue.TypeCode 属性是一个16位整型数据,它指明 TypedValue.Value 属性的数据类型,可接受的 TypeCode 值取决于 ResultBuffer 实例的使用范围。
例如,适用于扩展记录定义的 TypeCode 值就不适合于 XData。而Autodesk.AutoCAD.DatabaseServices.DxfCode 枚举类型定义的码值则描述了 ResultBuffer 可能的数据类型。
TypedValue.Value 属性是一个 System.Object 的实例,它可以包含任何类型的数据;但是,Value 的数据必须符合由 TypeCode 指明的类型。
创建 ResultBuffer 方法有两种:
1.一种是使用构造函数创建,即在声明 ResultBuffer 时将一个 TypedValue 作用参数传给 ResultBuffer:
2.另一种是使用 ResultBuffer.Add() 方法来添加 TypedValue,可以添加多个TypedValue,但总数据大小不能超过128K:
ResultBuffer resBuf = new ResultBuffer();
resBuf.Add(new TypedValue(1001, "appname")); //必须放在第一条添加,否则会报错
resBuf.Add(new TypedValue(1000, "作者:王"));
注意// resBuf 必须包含 1001 对应的值 就是应用程序名称
ResultBuffer resBuf = new ResultBuffer(new TypedValue((int)DxfCode.Text, "我的扩展数据"));
但是这里虽然是用等号赋值的,但是它并不一定会覆盖旧的扩展数据,一个实体,只有一个XData属性,但是里面可以记录多个不同应用程序名的扩展数据。
每次用“=”给实体的XData赋值时,如果XData里还没有这个应用程序的扩展数据,那么新赋的这些值,会被添加到原有的XData结尾去。
三.代码
通用代码:
/// <summary> /// 给指定的实体增加扩展数据 根据 DBObject /// </summary> /// <param name="db">db</param> /// <param name="obj">ent等</param> /// <param name="regAppName">扩展数据名</param> /// <param name="tv">扩展数据</param> public static void SetXData(Database db, DBObject obj, string regAppName, TypedValue[] tv) { using (Transaction tr = db.TransactionManager.StartTransaction()) { RegAppTable rat = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForWrite); using (ResultBuffer rb = new ResultBuffer(tv)) { obj.UpgradeOpen(); CheckAddAppName(tr, rat, regAppName); //注册并添加扩展数据名 obj.XData = rb; rb.Dispose(); tr.Commit(); } } }View Code
/// <summary> /// 注册并添加扩展数据名 /// </summary> /// <param name="regAppName"></param> public static void CheckAddAppName(Transaction tr, RegAppTable rat, string regAppName) { if (!rat.Has(regAppName)) { RegAppTableRecord ratr = new RegAppTableRecord(); ratr.Name = regAppName; rat.Add(ratr); tr.AddNewlyCreatedDBObject(ratr, true); } }View Code
/// <summary> /// 得到扩展数据 /// </summary> /// <param name="db">db</param> /// <param name="entId">实体Id</param> /// <param name="regAppName">扩展数据名</param> /// <param name="tv">扩展数据</param> /// <returns>true,false</returns> public static bool TryGetXData(Database db, ObjectId entId, string regAppName, out TypedValue[] tv) { Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { DBObject obj = tr.GetObject(entId, OpenMode.ForRead); using (ResultBuffer rb = obj.GetXDataForApplication(regAppName)) { if (rb != null) { tv = rb.AsArray(); return true; } else { tv = null; return false; } } } }View Code
四.总结
1.每一条扩展数据都必须以应用程序名开头。
2. XData数据形式类似字典Dictionary,但是此字典的key有一个,value可以是多个(一组或多组),这里的key必须按照DxfCode组码规则来,value也必须根据选定的组码选用约定好的数据形式。
3.一个实体可以有多个扩展数据,只要应用程序名不同即可(-3 ("firstapp" (1000 . "测试") (1040 . 800.0)) ("firstapp2" (1000 . "测试") (1040 . 800.0))))
注意:在项目开发中,CAD程序文件有可能被杀毒软件误杀掉扩展数据相关文件,建议少用XData,可以用Xrecord,其次XData数据的形式约束和长度约束也不是很便利。
版权提醒:
本人辛苦总结的文章最近被http://www.bubuko.com/网站原封不动的抄袭,请问你的良心何在,至少也要说一声转发吧,本人保留法律追究权利。
如果要转发本人文章,请标注转发字眼,尊重原创。