使用 C# 在分解后擦除 AutoCAD 绘图对象
Erasing AutoCAD drawing objects after exploding them, using C#
我正在处理一个任务,其中代码自动打开用户选择的绘图 [在 UI] 并选择绘图中的所有对象并开始分解所有对象直到它们不能再爆了这样做时我遇到了一个问题,原始的(未分解的 3D 对象)仍然存在于绘图中,由分解的对象叠加。 Explode 函数的每次递归调用都会创建该对象的新分解 3D 对象。
这是我正在处理的代码片段:
PromptSelectionResult ss = ed.SelectAll();
using (DocumentLock acLckDoc = doc.LockDocument())
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
objs = new DBObjectCollection();
foreach (SelectedObject so in ss.Value)
{
Entity ent = (Entity)tr.GetObject(so.ObjectId, OpenMode.ForWrite);
if (!(ent is Solid3d))
{
ent.Explode(objs);
ent.UpgradeOpen();
ent.Erase();
}
}
tr.Commit();
}
}
一旦控件进入 ent.Erase() 语句 - 它就会抛出异常,eCannotBeErasedByCaller。我不知道为什么?我已经解锁了所有图层,打开了用于写入的实体,CommandFlags 已设置为 Session 和 UsePickSet(全部打乱)。
有人有什么建议吗?
看你的描述,你可能需要一个递归爆炸。前段时间我围绕这个做了一个代码,用于其他类型的实体,但你可以调整它。
private List<DBObject> FullExplode(Entity ent)
{
// final result
List<DBObject> fullList = new List<DBObject>();
// explode the entity
DBObjectCollection explodedObjects = new DBObjectCollection();
ent.Explode(explodedObjects);
foreach (Entity explodedObj in explodedObjects)
{
// if the exploded entity is a blockref or mtext
// then explode again
if (explodedObj.GetType() == typeof(BlockReference) ||
explodedObj.GetType() == typeof(MText))
{
fullList.AddRange(FullExplode(explodedObj));
}
else
fullList.Add(explodedObj);
}
return fullList;
}
来源:http://adndevblog.typepad.com/infrastructure/2013/04/get-cogopoint-label-text.html
我终于找到了原始对象没有被擦除的原因。
在代码的前面部分,将 AutoCAD Plant3D dwg 导出到 AutoCAD (ExporttoAutoCAD / Saveas),这是在创建代理项。这些不能手动或通过代码删除。
唯一的方法是在导出文件之前分解 PipeLines 和 Inline 资产。如果您导出文件,这会自动发生,但如果您使用 saveas,则必须在导出之前分解管道组件导出文件。
浪费了很多时间了解原因,终于明白了!
我正在处理一个任务,其中代码自动打开用户选择的绘图 [在 UI] 并选择绘图中的所有对象并开始分解所有对象直到它们不能再爆了这样做时我遇到了一个问题,原始的(未分解的 3D 对象)仍然存在于绘图中,由分解的对象叠加。 Explode 函数的每次递归调用都会创建该对象的新分解 3D 对象。
这是我正在处理的代码片段:
PromptSelectionResult ss = ed.SelectAll();
using (DocumentLock acLckDoc = doc.LockDocument())
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
objs = new DBObjectCollection();
foreach (SelectedObject so in ss.Value)
{
Entity ent = (Entity)tr.GetObject(so.ObjectId, OpenMode.ForWrite);
if (!(ent is Solid3d))
{
ent.Explode(objs);
ent.UpgradeOpen();
ent.Erase();
}
}
tr.Commit();
}
}
一旦控件进入 ent.Erase() 语句 - 它就会抛出异常,eCannotBeErasedByCaller。我不知道为什么?我已经解锁了所有图层,打开了用于写入的实体,CommandFlags 已设置为 Session 和 UsePickSet(全部打乱)。
有人有什么建议吗?
看你的描述,你可能需要一个递归爆炸。前段时间我围绕这个做了一个代码,用于其他类型的实体,但你可以调整它。
private List<DBObject> FullExplode(Entity ent)
{
// final result
List<DBObject> fullList = new List<DBObject>();
// explode the entity
DBObjectCollection explodedObjects = new DBObjectCollection();
ent.Explode(explodedObjects);
foreach (Entity explodedObj in explodedObjects)
{
// if the exploded entity is a blockref or mtext
// then explode again
if (explodedObj.GetType() == typeof(BlockReference) ||
explodedObj.GetType() == typeof(MText))
{
fullList.AddRange(FullExplode(explodedObj));
}
else
fullList.Add(explodedObj);
}
return fullList;
}
来源:http://adndevblog.typepad.com/infrastructure/2013/04/get-cogopoint-label-text.html
我终于找到了原始对象没有被擦除的原因。
在代码的前面部分,将 AutoCAD Plant3D dwg 导出到 AutoCAD (ExporttoAutoCAD / Saveas),这是在创建代理项。这些不能手动或通过代码删除。 唯一的方法是在导出文件之前分解 PipeLines 和 Inline 资产。如果您导出文件,这会自动发生,但如果您使用 saveas,则必须在导出之前分解管道组件导出文件。
浪费了很多时间了解原因,终于明白了!