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/網站原封不動的抄襲,請問你的良心何在,至少也要說一聲轉發吧,本人保留法律追究權利。

   如果要轉發本人文章,請標注轉發字眼,尊重原創。

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM