- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I have some code that I have written, which is working, but I feel I'm losing the full understanding when it comes to blocks in AutoCAD and how they work in the .NET API.
There are block definitions, which reside in the Block Table, and are the blueprints.
There are block references which are "copies" of the definition. I start getting a little confused around BlockReference and BlockTableRecord. Are both BlockDefinitions and BlockReferences different types of BlockTableRecords? I know a Block Reference is the in space representation of a block, and it has a block table record property. Is that property a copy of the Block Definitions Block Table Record?
And how does this work with Dynamic blocks. When I use GetAnonymousBlockIds, am I getting Block References or Block Table Records?
Here is my code. As I said its working, I just want to make sure my understanding is robust enough to make my code robust for issues I might not have run into yet.
I'm going through an ObjectIdCollection and changing the layer of entities, and if its a block I am changing the layer for the entities contained inside it.
static bool CheckEntLayer(Entity ent, Transaction tr, out KeyValuePair<ObjectId, string> val)
{
val = new KeyValuePair<ObjectId, string>();
string entLayer = ent.Layer;
if (HandleBlock(ent, tr)) return false;
if (!_destinationLayers.Contains(entLayer))
{
if (_layerConversions.TryGetValue(entLayer, out string newLayer))
{
if (!_idLayerPairs.ContainsKey(ent.ObjectId)) val = new KeyValuePair<ObjectId, string>(ent.ObjectId, newLayer);
}
else
{
if (ent.EntityColor.IsByLayer && _layerColors.TryGetValue(entLayer, out var layerColor))
{
ent.UpgradeOpen();
ent.Color = layerColor;
}
if (!_idLayerPairs.ContainsKey(ent.ObjectId)) val = new KeyValuePair<ObjectId, string>(ent.ObjectId, "0");
}
ent.UpgradeOpen();
ent.Layer = "0";
}
else
{
if(!_idLayerPairs.ContainsKey(ent.ObjectId)) val = new KeyValuePair<ObjectId, string>(ent.ObjectId, entLayer);
}
return true;
}
static bool HandleBlock(Entity ent, Transaction tr)
{
if (ent.IsDerivedFrom(typeof(BlockReference)))
{
Dictionary<ObjectId, string> blockPieces = new Dictionary<ObjectId, string>();
BlockReference block = ent as BlockReference;
ObjectId btrId = block.IsDynamicBlock ? block.DynamicBlockTableRecord : block.BlockTableRecord;
BlockTableRecord dynBtr = tr.GetObject(btrId, OpenMode.ForRead, false, true) as BlockTableRecord;
foreach (ObjectId id in dynBtr)
{
id.TryGetRead<Entity>(tr, (idEnt, tran) =>
{
if(CheckEntLayer(idEnt, tr, out KeyValuePair<ObjectId, string> piece))
blockPieces.Add(piece.Key, piece.Value);
});
}
foreach (ObjectId id in block.AttributeCollection)
{
id.TryGetRead<AttributeReference>(tr, att =>
{
if (CheckEntLayer(att, tr, out KeyValuePair<ObjectId, string> piece))
blockPieces.Add(piece.Key, piece.Value);
att.RecordGraphicsModified(true);
});
}
ModifyBlockReferences(tr, block, dynBtr);
_blockIdLayerPairs.Add(ent.ObjectId, blockPieces);
return true;
}
return false;
}
private static void ModifyBlockReferences(Transaction tr, BlockReference block, BlockTableRecord dynBtr)
{
if (block.IsDynamicBlock)
{
var anonymousBlocks = dynBtr.GetAnonymousBlockIds();
anonymousBlocks.TryForEachWrite<BlockTableRecord>(tr, @Anonymous =>
{
foreach (ObjectId id in @Anonymous)
{
id.TryGetRead<Entity>(tr, refEnt =>
{
if (CheckEntLayer(refEnt, tr, out KeyValuePair<ObjectId, string> val))
_idLayerPairs.Add(val.Key, val.Value);
refEnt.RecordGraphicsModified(true);
});
}
});
}
else
{
dynBtr.GetBlockReferenceIds(true, true)
.TryForEachWrite<BlockReference>(tr, @Anonymous => { @Anonymous.RecordGraphicsModified(true); });
}
}
Solved! Go to Solution.