CAD.NET中使用XBindXrefs、BindXrefs雙重綁定參照的探討

来源:https://www.cnblogs.com/SHUN-ONCET/archive/2022/08/17/16593360.html
-Advertisement-
Play Games

/* CAD2023線上幫助鏈接 https://help.autodesk.com/view/OARX/2023/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_DatabaseServices_Database_XBindXrefs_ObjectI ...


/* CAD2023線上幫助鏈接 https://help.autodesk.com/view/OARX/2023/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_DatabaseServices_Database_XBindXrefs_ObjectIdCollection__MarshalAsUnmanagedType_U1__bool

* (註:本文僅為自己在實際工作中遇到的問題,所找到的一種解決方案,僅供參考、學習使用。若有不足處,歡迎在評論區留言糾正)
* 一、CAD原BindXrefs方法可直接對外部參照BlockTable的id集合綁定,當使用其綁定xrNode.BlockTableRecordId的集合或btr.ObjectId的集合時,往往會出現無法意料的異常,如eInvalidInput、eNullObjectId、eWrongObjectType
* 或各種圖層複原等,導致外部參照不能完全綁定,從而達不到圖紙的綁定期望。
*
* 二、例如本人遇到的外部參照綁定後圖層複原問題、綁定不徹底問題,它倆並不是每次綁定都會出現,而是不一樣的圖紙,隨機發生,只要一齣現,原圖紙無論怎樣處理,再綁定也不能消除異常,即這些問題具有不可預測性。
* 怎樣來處理諸如以上描述的問題,一直是棘手的事,也曾通過微軟bing、CAD二次開發群等方式搜索、咨詢XBindXrefs方法使用相關資料,未找到合理的解決方案。
*
* 三、根據CAD線上幫助文件對XBindXrefs方法描述“The ObjectIds in xrefSymbolIds must all be from the working database and they must all be from resolved xrefs”中發現,需要轉換資料庫後,再對參照符號表記錄id
* 集合綁定。且根據該方法對第一個參數的描述“Input collection of ObjectIds of SymbolTableRecord objects to be bound”,註意到應正確使用XBindXrefs和BindXrefs的順序。結合“xrefSymbolIds may contain ObjectIds
* for the following symbol table record types: BlockTableRecord, LayerTableRecord, LinetypeTableRecord, TextStyleTableRecord (if it does not represent a shape file),RegAppTableRecord, and DimStyleTableRecord
* 的描述,其中雖含塊表記錄,經實測,CAD原XBindXrefs方法僅可對圖層表記錄、線性表記錄、文字樣式表記錄、註冊程式表記錄、標註樣式表記錄進行綁定,除對符號表中的用戶坐標系表記錄、視口表記錄、視圖表記錄是不能綁定外,
* 塊表記錄卻也不能綁定,否則會出現eWrongObjectType異常。
*
* 四、最後經本人實際測試,得出CAD原生XBindXrefs和BindXrefs的結合使用可解決上述大部分異常問題的方式和註意事項,整理如下:
* 1)結合使用須前置的條件:資料庫轉換,利用WorkingDatabase;
* 2)使用順序:先XBindXrefs,再BindXrefs;
* 3)關於XBindXrefs可綁定的5個符號表記錄累加綁定效果:
*      a、單選XBindXrefs綁定圖層表記錄,可以解決絕大部分圖紙的綁定(本人暫未遇到不能綁定的情況,本選項為“無敵綁定”項)。
*      b、在選用a項綁定時,可能遇到的情況是,如屬性文字偏移(本人遇到),很少部分圖紙會出現,解決方法是選XBindXrefs綁定圖層表記錄、文字樣式表記錄即可。
*      c、除選用a項綁定,若單個單個累加其他剩下4個符號表記錄,大部分圖紙能正常綁定,少數圖紙會出現eWrongObjectType異常,建議根據所需動態選擇綁定的符號表記錄。
*      d、除選用a項綁定,其他4個符號表記錄,一一單選綁定,本人未進行測試,所需者可根據自身要求測試綁定效果。
*
* 五、附本人測試成功的封裝代碼。如有引用本文,請標識出處。
*/

using Autodesk.AutoCAD.DatabaseServices;
using System.Collections.Generic;
using AcCoreAp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
namespace Oncet.CAD { public static class XrefEx { /// <summary> /// XBindXrefs、BindXrefs雙重綁定參照。增加綁定符號表累計的選擇;增加儲存嵌套參照被卸載的字典ref方式 /// </summary> /// <param name="db">資料庫</param> /// <param name="symbolTableRecordNum">累計要綁定的符號表數量,預設為0。最小為0,最大為4。具體【0為"圖層表",1為"文字樣式表",2為"線型表",3為"註冊應用程式表",4為"標註樣式表"】</param> /// <param name="isNestedNodeNameDic">儲存嵌套參照被卸載的字典</param> public static void XBindXrefs(Database db, ref Dictionary<Handle, string> isNestedNodeNameDic, int symbolTableRecordNum = 0) {//資料庫轉換 var workingDb = HostApplicationServices.WorkingDatabase; HostApplicationServices.WorkingDatabase = db; string errorRemark = db.OriginalFileName;//標記可能出錯的文件名,在異常時使用; Dictionary<Handle, string> isNestedNodeName = isNestedNodeNameDic; try { db.ResolveXrefs(false, false);//解析資料庫 var bindXrefsIds = new ObjectIdCollection();//聲明要BindXrefs的集合 var xBindXrefsIds = new ObjectIdCollection();//聲明要XBindXrefs的集合 ObjectIdCollection isNestedIds = new ObjectIdCollection();//20220815 using (var tr = db.TransactionManager.StartTransaction()) { #region MyRegion20220815-批註原塊表參照的id集合獲取 var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);//塊表 foreach (ObjectId id in bt) { var btr = (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead); if (btr.IsFromExternalReference && btr.IsResolved) bindXrefsIds.Add(id); } #endregion #region MyRegion20220815補充是否被嵌套卸載的處理 XrefGraph xg = db.GetHostDwgXrefGraph(true); int xrefcount = xg.NumNodes; for (int j = 0; j < xrefcount; j++) { XrefGraphNode xrNode = xg.GetXrefNode(j); if (xrNode.XrefStatus == XrefStatus.Unloaded)//若文件已卸載 { ObjectId deTachId = xrNode.BlockTableRecordId; BlockTableRecord btr = (BlockTableRecord)tr.GetObject(deTachId, OpenMode.ForRead); if (btr.IsFromExternalReference) { if (!xrNode.IsNested)//若為非嵌套參照 { db.DetachXref(deTachId);//拆離已經卸載的非嵌套文件 } if (xrNode.IsNested)//若為嵌套參照 { isNestedIds.Add(deTachId); isNestedNodeName.Add(deTachId.Handle, xrNode.Name);//有嵌套參照,添加關鍵信息進字典,以傳出方法供綁定後刪除處理 } } } if (xrNode.XrefStatus == XrefStatus.Unreferenced)//若文件未參照 { db.DetachXref(xrNode.BlockTableRecordId);//拆離未參照的文件 } #region MyRegion使用此方法添加的xrNode.BlockTableRecordId,綁定中會隨機出現異常(勿用) //if (xrNode.XrefStatus == XrefStatus.Resolved)//若文件已解析 //{ // ObjectId bindXrefId = xrNode.BlockTableRecordId; // BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bindXrefId, OpenMode.ForRead); // if (btr.IsFromExternalReference) // { // xrefIds.Add(bindXrefId); // } //} #endregion } #endregion #region MyRegion20220814添加XBindXrefs符號表記錄id。根據symbolTableRecordNum值範圍0~4動態控制5個符號表記錄累加綁定需求 if (symbolTableRecordNum >= 0)//為0時被本人稱為“無敵綁定”項 { LayerTable layert = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;//圖層表 foreach (ObjectId id in layert) { LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(id, OpenMode.ForRead); if (ltr.IsResolved) { xBindXrefsIds.Add(ltr.ObjectId); } } } if (symbolTableRecordNum >= 1) { TextStyleTable textstylet = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;//文字樣式表 foreach (ObjectId id1 in textstylet) { TextStyleTableRecord textstyletr = (TextStyleTableRecord)tr.GetObject(id1, OpenMode.ForRead); if (textstyletr.IsResolved) { xBindXrefsIds.Add(textstyletr.ObjectId); } } } if (symbolTableRecordNum >= 3) { LinetypeTable linetypet = tr.GetObject(db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;//線型表 foreach (ObjectId id1 in linetypet) { LinetypeTableRecord linetr = (LinetypeTableRecord)tr.GetObject(id1, OpenMode.ForRead); if (linetr.IsResolved) { xBindXrefsIds.Add(linetr.ObjectId); } } } if (symbolTableRecordNum >= 2) { DimStyleTable dimt = tr.GetObject(db.DimStyleTableId, OpenMode.ForRead) as DimStyleTable;//標註樣式表 foreach (ObjectId id1 in dimt) { DimStyleTableRecord dtr = (DimStyleTableRecord)tr.GetObject(id1, OpenMode.ForRead); if (dtr.IsResolved) { xBindXrefsIds.Add(dtr.ObjectId); } } } if (symbolTableRecordNum >= 4) { RegAppTable regappt = tr.GetObject(db.RegAppTableId, OpenMode.ForRead) as RegAppTable;//註冊應用程式表 foreach (ObjectId id1 in regappt) { RegAppTableRecord regapptr = (RegAppTableRecord)tr.GetObject(id1, OpenMode.ForRead); if (regapptr.IsResolved) { xBindXrefsIds.Add(regapptr.ObjectId); } } } #region MyRegion20220814起初測試是將9大符號表記錄均加入的,但經實測不行。所以根據截取幫助文件中描述,僅添加了塊表外的5表記錄id ///xrefSymbolIds可能包含以下符號表記錄類型的 ObjectId: ///BlockTableRecord、LayerTableRecord、LinetypeTableRecord、TextStyleTableRecord(如果它不代表形狀文件)、RegAppTableRecord和DimStyleTableRecord。 ///20220814 //ViewportTable viewport = tr.GetObject(db.ViewportTableId, OpenMode.ForRead) as ViewportTable;//視口表 //foreach (ObjectId id1 in viewport) //{ // ViewportTableRecord viewportr = (ViewportTableRecord)tr.GetObject(id1, OpenMode.ForRead); // if (viewportr.IsResolved) // { // xrefIds1.Add(viewportr.ObjectId); // } //} //ViewTable viewt = tr.GetObject(db.ViewTableId, OpenMode.ForRead) as ViewTable;// 視圖表 //foreach (ObjectId id1 in viewt) //{ // ViewTableRecord viewtr = (ViewTableRecord)tr.GetObject(id1, OpenMode.ForRead); // if (viewtr.IsResolved) // { // xrefIds1.Add(viewtr.ObjectId); // } //} //UcsTable ucst = tr.GetObject(db.UcsTableId, OpenMode.ForRead) as UcsTable;// 用戶坐標系表 //foreach (ObjectId id1 in ucst) //{ // UcsTableRecord ucstr = (UcsTableRecord)tr.GetObject(id1, OpenMode.ForRead); // if (ucstr.IsResolved) // { // xrefIds1.Add(ucstr.ObjectId); // } //} #endregion #endregion } if (isNestedIds.Count > 0)//若有嵌套參照被卸載,重載 { db.ReloadXrefs(isNestedIds); } #region MyRegion20220814此處即為二者結合使用,且順序非常重要。若交換秩序,則會綁定無效,切勿交換!!! db.XBindXrefs(xBindXrefsIds, true);//20220814建議為true db.BindXrefs(bindXrefsIds, true);//20220814建議為true #endregion } catch (System.Exception ex) {
          throw new System.Exception(ex.Message);
          //AcCoreAp.ShowAlertDialog("Error: " + ex.Message);
       }
       finally
       {
         isNestedNodeNameDic
= isNestedNodeName;//20220815
         HostApplicationServices.WorkingDatabase = workingDb;
       }
    }
  }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 常用類 筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 包裝類 包裝類的分類 針對八種基本數據類型相應的引用類型—包裝類 有了類的特點,就可以調用類中的方法。 | 基本數據類型 | 包裝類 | | | | | boolean | B ...
  • 7.1 順序性場景 7.1.1 場景概述 假設我們要傳輸一批訂單到另一個系統,那麼訂單對應狀態的演變是有順序性要求的。 已下單 → 已支付 → 已確認 不允許錯亂! 7.1.2 順序級別 1)全局有序: 串列化。每條經過kafka的消息必須嚴格保障有序性。 這就要求kafka單通道,每個groupi ...
  • 前言 本文基於Dubbo2.6.x版本,中文註釋版源碼已上傳github:xiaoguyu/dubbo 負載均衡,英文名稱為Load Balance,其含義就是指將負載(工作任務)進行平衡、分攤到多個操作單元上進行運行。 例如:在Dubbo中,同一個服務有多個服務提供者,每個服務提供者所在的機器性能 ...
  • 大家好,我是三友~~ 上周花了一點時間從頭到尾、從無到有地搭建了一套RocketMQ的環境,覺得還挺easy的,所以就寫篇文章分享給大家。 整篇文章可以大致分為三個部分,第一部分屬於一些核心概念和工作流程的講解;第二部分就是純手動搭建了一套環境;第三部分是基於環境進行測試和集成到SpringBoot ...
  • 8、Fixture帶返回值 在fixture中我們可以使用yield或者return來返回我們需要的東西,如測試數據,資料庫連接對象,文件對象等。 沒有後置處理 直接採用return的方式返回數據(yield也可以) import pytest @pytest.fixture() def data_ ...
  • Java註解是一個很重要的知識點,掌握好Java註解有利於學習Java開發框架底層實現。@mikechen Java註解定義 Java註解又稱Java標註,是在 JDK5 時引入的新特性,註解(也被稱為元數據)。 Java註解它提供了一種安全的類似註釋的機制,用來將任何的信息或元數據(metadat ...
  • 1、登錄 1.1 登錄form表單 <form action="<%=request.getContextPath()%>/loginAnime" method="get"> <table border="1px" align="center" width="40%" cellspacing="0" ...
  • 來源:一尾流鶯 鏈接:https://juejin.cn/post/6994327298740600839 本文不做任何編輯器的比較,只是我本人日常使用 vscode 進行開發,並且比較喜歡折騰 vscode ,會到處找這一些好玩的插件,於是越攢越多,今天給大家推薦一下我收藏的 60 多個 vsco ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...