CAD二开---扩展数据XData

一.简述

       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/网站原封不动的抄袭,请问你的良心何在,至少也要说一声转发吧,本人保留法律追究权利。

   如果要转发本人文章,请标注转发字眼,尊重原创。

   

posted @ 2020-06-25 22:42  小王子的博客  阅读(330)  评论(0编辑  收藏