There are many blog posts related to insert blocks, like here. This post aims to show a simple but yet reusable sample.
Basically to insert a block from an external drawing, it is required to insert the external .dwg into the main host .dwg, and then create a new block reference pointing to it. One additional trick is to set it annotative in case the source .dwg is already marked as annotative.
This sample is heavily based on this blog post, but jig features were removed.
[CommandMethod("createBlock")]
public static void CmdCreateBlock()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptStringOptions pso =
new PromptStringOptions(
"\nEnter block name: ");
PromptResult pr = ed.GetString(pso);
if (pr.Status != PromptStatus.OK) return;
PromptPointOptions ppo =
new PromptPointOptions(
"\nEntre block position: ");
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK) return;
CreateBlockReference(
Application.DocumentManager.
MdiActiveDocument.Database,
pr.StringResult, ppr.Value);
}
public static ObjectId GetBlockDefinition(
Database db, string blockName)
{
// Get the block definition by name
using (Transaction trans = db.
TransactionManager.StartTransaction())
{
BlockTable bt = trans.GetObject(
db.BlockTableId, OpenMode.ForRead)
as BlockTable;
if (!bt.Has(blockName)) return ObjectId.Null;
return bt[blockName];
}
}
// Place the reference at the model space
public static bool CreateBlockReference(
Database db, string blockName, Point3d position)
{
return CreateBlockReference(db,
db.CurrentSpaceId, blockName,
position);
}
// Specifying the host space (e.g. model space)
public static bool CreateBlockReference(
Database db, ObjectId hostSpaceId,
string blockName, Point3d position)
{
// First let’s get the name of the block
ObjectId blockDefId = GetBlockDefinition(
db, blockName);
bool blockDefIsAnnotative = false;
using (Transaction trans = db.
TransactionManager.StartTransaction())
{
if (blockDefId.IsNull)
{
// The definition with this name do not exist
// Try insert if is a file name
// If not possible, the file do not exist
if (!System.IO.File.Exists(blockName)) return false;
// Insert from external file
using (Database sourceDb = new Database(false, true))
{
sourceDb.ReadDwgFile(blockName,
FileOpenMode.OpenForReadAndAllShare,
true, string.Empty);
blockName = SymbolUtilityServices.RepairSymbolName(
SymbolUtilityServices.GetSymbolNameFromPathName(
blockName, "dwg"), false);
blockDefId = db.Insert(blockName, sourceDb, false);
blockDefIsAnnotative = db.AnnotativeDwg;
}
}
// Create the block reference and
BlockReference blockRef = new BlockReference(
position, blockDefId);
// Start annot-scale support code
BlockTableRecord blockDef = trans.GetObject(
blockDefId, OpenMode.ForRead) as BlockTableRecord;
// If the source was annotative, then set the block as
if (blockDefIsAnnotative)
{
blockDef.Annotative = AnnotativeStates.True;
ObjectContextManager ocm = db.ObjectContextManager;
ObjectContextCollection occ =
ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
ObjectContexts.AddContext(blockRef, occ.CurrentContext);
}
// If all is OK, let’s go and add the
// entity to the specified space
BlockTableRecord hostSpace = trans.GetObject(
hostSpaceId, OpenMode.ForWrite) as BlockTableRecord;
hostSpace.AppendEntity(blockRef);
trans.AddNewlyCreatedDBObject(blockRef, true);
// Add the attributes
foreach (ObjectId entId in blockDef)
{
AttributeDefinition attDef = trans.GetObject(
entId, OpenMode.ForRead) as AttributeDefinition;
if (attDef == null) continue;
// Create the attribute reference
AttributeDefinition ad = (AttributeDefinition)attDef;
AttributeReference ar = new AttributeReference();
ar.SetAttributeFromBlock(ad, blockRef.BlockTransform);
blockRef.AttributeCollection.AppendAttribute(ar);
trans.AddNewlyCreatedDBObject(ar, true);
}
trans.Commit();
}
return true;
}

Leave a Reply