翻譯並引自Kean's blog的兩篇文章:html
http://through-the-interface.typepad.com/through_the_interface/2006/08/import_blocks_f.html.數據庫
http://through-the-interface.typepad.com/through_the_interface/2006/08/breaking_it_dow.htmlapp
咱們將使用一箇中介「side database」-先把dwg讀取在內存中,而不是直接導入Autocad編輯器,以後再將「塊」導入到咱們的正在運行的編輯器(Autocad文件數據庫的結構,請參看相關資料)。編輯器
下面使C#代碼,其中的註釋說明了每條的功用。以後,咱們也將關鍵語句,進行分析。ide
1 using System; 2 using Autodesk.AutoCAD; 3 using Autodesk.AutoCAD.Runtime; 4 using Autodesk.AutoCAD.Geometry; 5 using Autodesk.AutoCAD.ApplicationServices; 6 using Autodesk.AutoCAD.DatabaseServices; 7 using Autodesk.AutoCAD.EditorInput; 8 using System.Collections.Generic; 9 10 namespace BlockImport 11 { 12 publicclassBlockImportClass 13 { 14 [CommandMethod("IB")] 15 publicvoid ImportBlocks() 16 { 17 DocumentCollection dm = 18 Application.DocumentManager; 19 Editor ed = dm.MdiActiveDocument.Editor; 20 Database destDb = dm.MdiActiveDocument.Database; 21 Database sourceDb = newDatabase(false, true); 22 PromptResult sourceFileName; 23 try 24 { 25 // Get name of DWG from which to copy blocks 26 sourceFileName = 27 ed.GetString("\nEnter the name of the source drawing: "); 28 // Read the DWG into a side database 29 sourceDb.ReadDwgFile(sourceFileName.StringResult, 30 System.IO.FileShare.Read, 31 true, 32 ""); 33 34 // Create a variable to store the list of block identifiers 35 ObjectIdCollection blockIds = newObjectIdCollection(); 36 37 Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = 38 sourceDb.TransactionManager; 39 40 using (Transaction myT = tm.StartTransaction()) 41 { 42 // Open the block table 43 BlockTable bt = 44 (BlockTable)tm.GetObject(sourceDb.BlockTableId, 45 OpenMode.ForRead, 46 false); 47 48 // Check each block in the block table 49 foreach (ObjectId btrId in bt) 50 { 51 BlockTableRecord btr = 52 (BlockTableRecord)tm.GetObject(btrId, 53 OpenMode.ForRead, 54 false); 55 // Only add named & non-layout blocks to the copy list 56 if (!btr.IsAnonymous && !btr.IsLayout) 57 blockIds.Add(btrId); 58 btr.Dispose(); 59 } 60 } 61 // Copy blocks from source to destination database 62 IdMapping mapping = newIdMapping(); 63 sourceDb.WblockCloneObjects(blockIds, 64 destDb.BlockTableId, 65 mapping, 66 DuplicateRecordCloning.Replace, 67 false); 68 ed.WriteMessage("\nCopied " 69 + blockIds.Count.ToString() 70 + " block definitions from " 71 + sourceFileName.StringResult 72 + " to the current drawing."); 73 } 74 catch(Autodesk.AutoCAD.Runtime.Exception ex) 75 { 76 ed.WriteMessage("\nError during copy: " + ex.Message); 77 } 78 sourceDb.Dispose(); 79 } 80 } 81 }
首先,Line21,咱們聲明並舉例了一個Database對象,這樣就會在內存中開闢必定空間(也就是咱們說的side database),這個空間對於咱們是能夠進入的,對於Autocad編輯器是不能夠的。其中,第1個參數(buildDefaultDrawing)要設置爲false,若是設置爲true,則函數不會反饋錯誤,所以你不知道程序發生了什麼。在下面兩種狀況中,你纔會把buildDefaultDrawing設置爲true:函數
1.你本身創造一個dwg文件,而不是從其餘地方讀取來;佈局
2.從其餘地方讀取來,並且dwg文件的版本在R12及以前。ui
(版本對照以下:spa
AC1.50 = R2.05
AC1002 = R2.6
AC1004 = R9
AC1006 = R10
AC1009 = R11/R12
AC1012 = R13
AC1014 = R14
AC1015 = 2000/2000i/2002
AC1018 = 2004/2005/2006
AC1021 = 2007翻譯
)
下一步,Line26,27,咱們要求用戶輸入想要引入的文件地址。這裏咱們沒有檢查用戶是否輸入內容或者輸入的內容是否存在,是由於接下來的ReadDwgFile()方法在不能讀取文件時,會拋出一個error;
接下來,Line29,30,將文件內容讀取到side database.而且咱們在Line35,咱們創造一個塊集合(一樣,請參考Autocad文件數據庫的結構);
下面的最爲關鍵,Line40 tm.StartTransaction() 纔是與CAD編輯器交互的接口。其中,運用循環將有名字或者未佈局的塊收集起來,看代碼就不過多解釋了。這個函數WblockCloneObjects()中最後一個參數,REPLACE則擦除以前的內容覆蓋寫,若是設爲IGNORE,則續寫。