Hello,
I'm using C# with AutoCAD 2013.
How to insert block [from file] in "Layout" / "Viewport" without opening the drawing file.
I think, I'm missing something here.
code
[CommandMethod("BI_memory")] public void BlockInsert_memory() { string blockQualifiedFileName = "D:\\AutoCAD\\AL2.dwg"; //block dwg string blockName = "3Dblock"; //block name Database db = new Database(false, true); string Answer_File = "c:\\test1.dwg"; // Insert Drawing file db.ReadDwgFile(Answer_File, System.IO.FileShare.Read, true, string.Empty); using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (!bt.Has(blockName)) { Database tmpDb = new Database(false, true); tmpDb.ReadDwgFile(blockQualifiedFileName, System.IO.FileShare.Read, true, ""); db.Insert(blockName, tmpDb, true); } double XX = 267.0; double YY = 165.0; double ZZ = 0.0; BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); BlockReference br = new BlockReference(new Point3d(XX, YY, ZZ), bt[blockName]); btr.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); tr.Commit(); } }
Please suggest me with sample.
Thanks in advance,
thenndral
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
What issue did you ran into with the code? What did you think was missing?
If I am not mistaken, you want to insert a block into a give layout (paperspace), not into ModelSpace. your referring "Viewport" is irrelevant here.
Your problem is here:
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
Database.CurrentSpaceId for a side database that is not opened in AutoCAD editor, refers to the CURRENT space when the database was last saved, which could be either ModelSpace or one of the PaperSpace. If your code is to work, you have to bet on that the drawing opened in side database is ALWAYS saved and closed when the desired Layout/PaperSpace is the avtive one.
Since a drawing could have multiple Layouts with different names, you'd better know the layout name and search the Layout table of the database to identify the layout you want to insert block into, then you can get the cooresponding BlockTableRecord (corresponding PaperSpace). This way, you do not have to rely on a layout was current space before the drawiing was saved and closed.
Other issues with your code:
1. You need to open the side database for inserting block with FieleShare.ReadWrite, if after inserting the drawing you need to save it;
2. You need to dispose the 2 databases your code creates.
Following are the code that works for me:
using System.IO; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Geometry; using CadApp = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(InsertBlockIntoSideDatabase.MyCadCommands))] namespace InsertBlockIntoSideDatabase { public class MyCadCommands { [CommandMethod("InsBlk")] public static void RunMyCadCommand() { string sideFile = @"C:\Temp\test.dwg"; string blockFile =@"C:\Temp\TestBlock.dwg"; string blockName = Path.GetFileNameWithoutExtension(blockFile); string layoutName = "Layout1"; Document dwg = CadApp.DocumentManager.MdiActiveDocument; Editor ed = dwg.Editor; using (Database db = new Database(false, true)) { db.ReadDwgFile(sideFile, FileShare.ReadWrite, true, string.Empty); bool blockInserted = false; using (Transaction tr = db.TransactionManager.StartTransaction()) { ObjectId brId = ObjectId.Null; BlockTable bt = (BlockTable)tr.GetObject( db.BlockTableId, OpenMode.ForRead); if (!bt.Has(blockName)) { using (Database tmpDb = new Database(false, true)) { tmpDb.ReadDwgFile(blockFile, System.IO.FileShare.Read, true, ""); brId = db.Insert(blockName, tmpDb, true); } } else { brId = bt[blockName]; } //Find target layout ObjectId layoutId=ObjectId.Null; DBDictionary dic = (DBDictionary)tr.GetObject( db.LayoutDictionaryId, OpenMode.ForRead); try { layoutId = dic.GetAt(layoutName); } catch { } if (!layoutId.IsNull) { Layout layout = (Layout)tr.GetObject(layoutId, OpenMode.ForRead); ObjectId spaceId = layout.BlockTableRecordId; double XX = 0.0; double YY = 0.0; double ZZ = 0.0; BlockTableRecord btr = (BlockTableRecord)tr.GetObject( spaceId, OpenMode.ForWrite); BlockReference br = new BlockReference( new Point3d(XX, YY, ZZ), bt[blockName]); br.SetDatabaseDefaults(db); btr.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); tr.Commit(); blockInserted = true; } else { ed.WriteMessage( "\nDrawing does not have layout \"{0}\"!", layoutName); } } if (blockInserted) db.SaveAs(sideFile, DwgVersion.Current); } } } }
HTH
Norman Yuan
Hello,
Thanks for your brief answer.
I understand, where I did mistake.
I accecpt your solution.
Thanks again,
thenndral.