Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inserting a preexisting AutoCAD drawing into a current drawing

I'm trying to programmatically insert a block from a pre-existing drawing into the current drawing a plugin is running on. To do that, I have a button on my C#.NET form call the following method

public void MakeAndInsertObject() //Method to add all windows and doors templates to drawing database for use later
{
    Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; //Stores the active document
    Editor ed = doc.Editor; //Stores the document's editor
    Database dtb = ed.Document.Database; //Stores the database from the editor

    Transaction tr = dtb.TransactionManager.StartTransaction(); //Start a transaction with the document's database
    DocumentLock docLock = doc.LockDocument();

    using (tr)    
    using (docLock)
    {
        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(dtb.CurrentSpaceId, OpenMode.ForWrite); //Opens the block table record so you can write to it
        BlockTableRecord newBlockDef = new BlockTableRecord(); //Creates a new record in the block table
        BlockTable blockTable = (BlockTable)tr.GetObject(dtb.BlockTableId, OpenMode.ForWrite); //Opens the block table so it can be written to
        //Pointing new block to correct drawing file
        newBlockDef.Name = "Door";
        newBlockDef.PathName = "C:/Users/Administrator/Documents/All Code/clearspan-autocad-tools-development/Templates/locks/DOOR.dwg";
        blockTable.Add(newBlockDef); //Adds the block table record to the block table
        BlockReference newBlock = new BlockReference(new Point3d(0, 0, 0), newBlockDef.ObjectId); //Insert a block reference with the newly created block
        btr.AppendEntity(newBlock); //Inserts the block into the current space (Model or Paper) via the block table record
        //Updates the Transaction with all new database objects
        tr.AddNewlyCreatedDBObject(newBlockDef, true);
        tr.AddNewlyCreatedDBObject(newBlock, true);
        tr.Commit(); //Applies all changes made as part of the current transaction
        tr.Dispose();
    }
}

The code fully executes but the block in my DOOR.dwg file does not appear at location (0, 0, 0) and I do not know why it doesn't

like image 241
Nick Gilbert Avatar asked Nov 11 '14 15:11

Nick Gilbert


1 Answers

I took a snippet from Keen Walmsley and edited it to not be so cumbersome and more legible. This is pretty basic. You should read over some of Keen's stuff it is pretty good and he is very descriptive in his notes. see code below for usage.

public void ImportBlocks()
{
    DocumentCollection dm =
    Application.DocumentManager;
    Editor ed = dm.MdiActiveDocument.Editor;
    Database destDb = dm.MdiActiveDocument.Database;
    Database sourceDb = new Database(false, true);
    try
    {
        // Get name of DWG from which to copy blocks
        var sourceFileName = ed.GetString("\nEnter the path of the source drawing: ");

        // Read the DWG into a side database
        sourceDb.ReadDwgFile(sourceFileName.StringResult, System.IO.FileShare.Read, true, "");

        // Create a variable to store the list of block identifiers
        ObjectIdCollection blockIds = new ObjectIdCollection();

        var tm = sourceDb.TransactionManager;

        using (var myT = tm.StartOpenCloseTransaction())
        {
            // Open the block table
            BlockTable bt = (BlockTable)myT.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);

            // Check each block in the block table
            foreach (ObjectId btrId in bt)
            {
                BlockTableRecord btr =
                (BlockTableRecord)myT.GetObject(btrId, OpenMode.ForRead, false);

                // Only add named & non-layout blocks to the copy list
                if (!btr.IsAnonymous && !btr.IsLayout)
                    blockIds.Add(btrId);
                btr.Dispose();
            }
        }
        // Copy blocks from source to destination database
        var mapping = new IdMapping();
        sourceDb.WblockCloneObjects(blockIds,
            destDb.BlockTableId,
            mapping,
            DuplicateRecordCloning.Replace,
            false);
    }
    catch(Autodesk.AutoCAD.Runtime.Exception ex)
    {
        ed.WriteMessage("\nError during copy: " + ex.Message);
    }
    sourceDb.Dispose();
}

Just out of curiosity, If someone had developed a python API for use in AutoCAD, Would you use it? or give it a shot?

like image 104
Trae Moore Avatar answered Nov 11 '22 22:11

Trae Moore