- UID
- 658062
- 积分
- 2147
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2008-10-22
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
Exploding nested AutoCAD blocks using .NET Some time ago I posted about how to use Entity.Explode() to do something similar to AutoCAD’s EXPLODE command. At the time it was mentioned in the comments that BlockReference.ExplodeToOwnerSpace() had some relative benefits, but it’s taken me some time to code up a simple sample to show how you might use it (Patrick’s recent comment reminded me I ought to, though).
Anyway, to end the week I thought I’d throw together a quick sample. BlockReference.ExplodeToOwnerSpace() doesn’t return a list of created objects, so I opted to capture this using a Database.ObjectAppended event handler and then recursively call our custom ExplodeBlock() function for any nested blocks that get created. We also then erase the originating entity (or entities, if called recursively), just as the EXPLODE command might.
Here’s the C# code:
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.EditorInput;
- using Autodesk.AutoCAD.Runtime;
- namespace Explosions
- {
- public class Commands
- {
- [CommandMethod("EB")]
- public void ExplodeBock()
- {
- var doc = Application.DocumentManager.MdiActiveDocument;
- if (doc == null)
- return;
- var ed = doc.Editor;
- var db = doc.Database;
- // Ask the user to select the block
- var peo = new PromptEntityOptions("\nSelect block to explode");
- peo.SetRejectMessage("Must be a block.");
- peo.AddAllowedClass(typeof(BlockReference), false);
- var per = ed.GetEntity(peo);
- if (per.Status != PromptStatus.OK)
- return;
- using (var tr = db.TransactionManager.StartTransaction())
- {
- // Call our explode function recursively, starting
- // with the top-level block reference
- // (you can pass false as a 4th parameter if you
- // don't want originating entities erased)
- ExplodeBlock(tr, db, per.ObjectId);
- tr.Commit();
- }
- }
- private void ExplodeBlock(
- Transaction tr, Database db, ObjectId id, bool erase = true
- )
- {
- // Open out block reference - only needs to be readable
- // for the explode operation, as it's non-destructive
- var br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
- // We'll collect the BlockReferences created in a collection
- var toExplode = new ObjectIdCollection();
- // Define our handler to capture the nested block references
- ObjectEventHandler handler =
- (s, e) =>
- {
- if (e.DBObject is BlockReference)
- {
- toExplode.Add(e.DBObject.ObjectId);
- }
- };
- // Add our handler around the explode call, removing it
- // directly afterwards
- db.ObjectAppended += handler;
- br.ExplodeToOwnerSpace();
- db.ObjectAppended -= handler;
- // Go through the results and recurse, exploding the
- // contents
- foreach (ObjectId bid in toExplode)
- {
- ExplodeBlock(tr, db, bid, erase);
- }
- // We might also just let it drop out of scope
- toExplode.Clear();
- // To replicate the explode command, we're delete the
- // original entity
- if (erase)
- {
- br.UpgradeOpen();
- br.Erase();
- br.DowngradeOpen();
- }
- }
- }
- }
|
|