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

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

       

  • 相关阅读:
    Mvc分页:为IQueryable定义一个扩展方法,直接反回PagedList<T>结果集
    从零开始一起学习SLAM | 相机成像模型
    从零开始一起学习SLAM | 为啥需要李群与李代数?
    从零开始一起学习SLAM | 三维空间刚体的旋转
    从零开始一起学习SLAM | 为什么要用齐次坐标?
    从零开始一起学习SLAM | C++新特性要不要学?
    从零开始一起学习SLAM | SLAM有什么用?
    从零开始一起学习SLAM | 学习SLAM到底需要学什么?
    2019年度【计算机视觉&机器学习&人工智能】国际重要会议汇总
    从零开始一起学习SLAM | 为什么要学SLAM?
  • 原文地址:https://www.cnblogs.com/xiaowangzi1987/p/13193276.html
Copyright © 2011-2022 走看看