Import a dynamic block with Database.Insert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I have the attached file "LP_200_EXISTING.dwg". The contents of that DWG file were made by taking a dynamic block with multiple visibility states, and exploding it.
If i manually run the -INSERT command and provide it with the full path to the location of this DWG file on my computer, it inserts the contents of that DWG file into my drawing as a dynamic block, and everything looks and works as expected. As you can see o the screenshot below, all of the dynamic block attributes are showing underneath the "Custom" heading
Im now trying to replicate this -INSERT behaviour in my code which is below
[CommandMethod("JCB-PLACEBLOCK")]
public static void PlaceBlock(ContentBrowserMessage message)
{
var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
try
{
string filepath = @"C:\Users\Public\Documents\Jacobs Content Library\Temp Upload\LP_200_EXISTING.dwg";
string blockName = System.IO.Path.GetFileNameWithoutExtension(filepath);
using (var docLock = doc.LockDocument())
using (var tr = db.TransactionManager.StartTransaction())
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
ObjectId blkDefId = ObjectId.Null;
// First, load in the DWG file that contains the block we want to insert
using (Database blkDb = new Database(false, true))
{
HostApplicationServices.WorkingDatabase = blkDb;
// Read in the block DWG file into the temporary database
blkDb.ReadDwgFile(filepath, System.IO.FileShare.Read, false, null);
blkDb.CloseInput(false);
// Import contents of DWG file into destination database
blkDefId = db.Insert(blockName + "2", blkDb, true);
HostApplicationServices.WorkingDatabase = db;
}
// Ask user to place the block
PromptPointResult ppr = ed.GetPoint("Select Point to insert block");
if (ppr.Status == PromptStatus.OK)
{
// Get the model/paper space the user is currently in
var insertSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
BlockTableRecord blockDef = (BlockTableRecord)tr.GetObject(blkDefId, OpenMode.ForRead);
// Create new block reference
using (BlockReference newBlkRef = new BlockReference(ppr.Value, blkDefId))
{
// Add block to the relevat model/paper space
insertSpace.AppendEntity(newBlkRef);
tr.AddNewlyCreatedDBObject(newBlkRef, true);
// Set "normal" attributes
foreach (ObjectId id in blockDef)
{
DBObject obj = id.GetObject(OpenMode.ForRead);
AttributeDefinition attDef = obj as AttributeDefinition;
if ((attDef != null) && (!attDef.Constant))
{
using (AttributeReference attRef = new AttributeReference())
{
attRef.SetAttributeFromBlock(attDef, newBlkRef.BlockTransform);
attRef.TextString = attDef.TextString; // Set default value
//Add the AttributeReference to the BlockReference
newBlkRef.AttributeCollection.AppendAttribute(attRef);
tr.AddNewlyCreatedDBObject(attRef, true);
}
}
}
}
}
// Commit transaction
tr.Commit();
// Force user view to refresh so they can see the newly updated block definition
ed.Regen();
}
}
catch(System.Exception ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
HostApplicationServices.WorkingDatabase = db;
}
}
but when i run this, the block does get inserted, but i don't see any of the dynamic block attributes (I'm missing all the attributes under the "Custom" header, which also doesn't exist)
Is there anything I've missed to make this work for dynamic blocks? (This code works fine for a "normal" block)
Also, i was getting an "eSelfReference" error when running the db.Insert command. I managed to get around it by changing the name of the block I wanted to create. (This is why the block name is blockName + "2" in my code above) It appears i can't have it the same name as the DWG/database file I'm trying to copy the contents from. Is this correct?