有没有办法使用 C# 获取 autocad (.dwg) 中的所有多段线?
Is there a way to get all Polylines in autocad (.dwg) using C#?
我不想在运行时 select 特定的多段线。有没有一种方法可以在运行时使用 C# 在没有 selection 的情况下直接获取 .dwg 文件中的所有多段线? AutoCAD有一个叫DATAEXTRACTION的命令可以获取不同对象的相关信息(例如折线、圆、点...等),但我不知道它是否可以在C#中调用和使用。
仅供参考:在运行时从
http://through-the-interface.typepad.com/through_the_interface/2007/04/iterating_throu.html:
获取特定折线的示例代码
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
Polyline lwp = obj as Polyline; // Get the selected polyline during runtime
...
}
听起来您正在寻找类似的东西。如果不需要,请删除图层标准。
public ObjectIdCollection SelectAllPolylineByLayer(string sLayer)
{
Document oDwg = Application.DocumentManager.MdiActiveDocument;
Editor oEd = oDwg.Editor;
ObjectIdCollection retVal = null;
try {
// Get a selection set of all possible polyline entities on the requested layer
PromptSelectionResult oPSR = null;
TypedValue[] tvs = new TypedValue[] {
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<and"),
new TypedValue(Convert.ToInt32(DxfCode.LayerName), sLayer),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<or"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "LWPOLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE2D"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE3d"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "or>"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "and>")
};
SelectionFilter oSf = new SelectionFilter(tvs);
oPSR = oEd.SelectAll(oSf);
if (oPSR.Status == PromptStatus.OK) {
retVal = new ObjectIdCollection(oPSR.Value.GetObjectIds());
} else {
retVal = new ObjectIdCollection();
}
} catch (System.Exception ex) {
ReportError(ex);
}
return retVal;
}
2015 年 1 月 12 日更新
这同样有效,让您不必处理所有键入的值...
我写了一篇关于这个主题的博客post,Check it out.
public IList<ObjectId> GetIdsByType()
{
Func<Type,RXClass> getClass = RXObject.GetClass;
// You can set this anywhere
var acceptableTypes = new HashSet<RXClass>
{
getClass(typeof(Polyline)),
getClass(typeof (Polyline2d)),
getClass(typeof (Polyline3d))
};
var doc = Application.DocumentManager.MdiActiveDocument;
using (var trans = doc.TransactionManager.StartOpenCloseTransaction())
{
var modelspace = (BlockTableRecord)
trans.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(doc.Database), OpenMode.ForRead);
var polylineIds = (from id in modelspace.Cast<ObjectId>()
where acceptableTypes.Contains(id.ObjectClass)
select id).ToList();
trans.Commit();
return polylineIds;
}
}
我知道这是个老问题,但也许有人会觉得它有用。
使用 SelectionFilter 来 select 只打开或关闭折线(任何类型的折线):
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
int polylineState = 1; // 0 - closed, 1 - open
TypedValue[] vals= new TypedValue[]
{
new TypedValue((int)DxfCode.Operator, "<or"),
// This catches Polyline object.
new TypedValue((int)DxfCode.Operator, "<and"),
new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
new TypedValue(70, polylineState),
new TypedValue((int)DxfCode.Operator, "and>"),
new TypedValue((int)DxfCode.Operator, "<and"),
new TypedValue((int)DxfCode.Start, "POLYLINE"),
new TypedValue((int)DxfCode.Operator, "<or"),
// This catches Polyline2d object.
new TypedValue(70, polylineState),
// This catches Polyline3d object.
new TypedValue(70, 8|polylineState),
new TypedValue((int)DxfCode.Operator, "or>"),
new TypedValue((int)DxfCode.Operator, "and>"),
new TypedValue((int)DxfCode.Operator, "or>"),
};
SelectionFilter filter = new SelectionFilter(vals);
PromptSelectionResult prompt = ed.GetSelection(filter);
// If the prompt status is OK, objects were selected
if (prompt.Status == PromptStatus.OK)
{
SelectionSet sset = prompt.Value;
Application.ShowAlertDialog($"Number of objects selected: {sset.Count.ToString()}");
}
else
{
Application.ShowAlertDialog("Number of objects selected: 0");
}
所有绘图实体列表:link 1 (older) or link 2 (newer)
在this link中我们看到值为1的代码70是闭合折线。
并且在 this link 中我们看到这同样适用于折线 2d/3d,但另外使用值 8 我们定义它是 2d 还是 3d 折线。值可以按位组合,因此 8|1 表示封闭的 3d 折线。
我不想在运行时 select 特定的多段线。有没有一种方法可以在运行时使用 C# 在没有 selection 的情况下直接获取 .dwg 文件中的所有多段线? AutoCAD有一个叫DATAEXTRACTION的命令可以获取不同对象的相关信息(例如折线、圆、点...等),但我不知道它是否可以在C#中调用和使用。
仅供参考:在运行时从
http://through-the-interface.typepad.com/through_the_interface/2007/04/iterating_throu.html:
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
Polyline lwp = obj as Polyline; // Get the selected polyline during runtime
...
}
听起来您正在寻找类似的东西。如果不需要,请删除图层标准。
public ObjectIdCollection SelectAllPolylineByLayer(string sLayer)
{
Document oDwg = Application.DocumentManager.MdiActiveDocument;
Editor oEd = oDwg.Editor;
ObjectIdCollection retVal = null;
try {
// Get a selection set of all possible polyline entities on the requested layer
PromptSelectionResult oPSR = null;
TypedValue[] tvs = new TypedValue[] {
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<and"),
new TypedValue(Convert.ToInt32(DxfCode.LayerName), sLayer),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "<or"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "LWPOLYLINE"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE2D"),
new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE3d"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "or>"),
new TypedValue(Convert.ToInt32(DxfCode.Operator), "and>")
};
SelectionFilter oSf = new SelectionFilter(tvs);
oPSR = oEd.SelectAll(oSf);
if (oPSR.Status == PromptStatus.OK) {
retVal = new ObjectIdCollection(oPSR.Value.GetObjectIds());
} else {
retVal = new ObjectIdCollection();
}
} catch (System.Exception ex) {
ReportError(ex);
}
return retVal;
}
2015 年 1 月 12 日更新
这同样有效,让您不必处理所有键入的值...
我写了一篇关于这个主题的博客post,Check it out.
public IList<ObjectId> GetIdsByType()
{
Func<Type,RXClass> getClass = RXObject.GetClass;
// You can set this anywhere
var acceptableTypes = new HashSet<RXClass>
{
getClass(typeof(Polyline)),
getClass(typeof (Polyline2d)),
getClass(typeof (Polyline3d))
};
var doc = Application.DocumentManager.MdiActiveDocument;
using (var trans = doc.TransactionManager.StartOpenCloseTransaction())
{
var modelspace = (BlockTableRecord)
trans.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(doc.Database), OpenMode.ForRead);
var polylineIds = (from id in modelspace.Cast<ObjectId>()
where acceptableTypes.Contains(id.ObjectClass)
select id).ToList();
trans.Commit();
return polylineIds;
}
}
我知道这是个老问题,但也许有人会觉得它有用。
使用 SelectionFilter 来 select 只打开或关闭折线(任何类型的折线):
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
int polylineState = 1; // 0 - closed, 1 - open
TypedValue[] vals= new TypedValue[]
{
new TypedValue((int)DxfCode.Operator, "<or"),
// This catches Polyline object.
new TypedValue((int)DxfCode.Operator, "<and"),
new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
new TypedValue(70, polylineState),
new TypedValue((int)DxfCode.Operator, "and>"),
new TypedValue((int)DxfCode.Operator, "<and"),
new TypedValue((int)DxfCode.Start, "POLYLINE"),
new TypedValue((int)DxfCode.Operator, "<or"),
// This catches Polyline2d object.
new TypedValue(70, polylineState),
// This catches Polyline3d object.
new TypedValue(70, 8|polylineState),
new TypedValue((int)DxfCode.Operator, "or>"),
new TypedValue((int)DxfCode.Operator, "and>"),
new TypedValue((int)DxfCode.Operator, "or>"),
};
SelectionFilter filter = new SelectionFilter(vals);
PromptSelectionResult prompt = ed.GetSelection(filter);
// If the prompt status is OK, objects were selected
if (prompt.Status == PromptStatus.OK)
{
SelectionSet sset = prompt.Value;
Application.ShowAlertDialog($"Number of objects selected: {sset.Count.ToString()}");
}
else
{
Application.ShowAlertDialog("Number of objects selected: 0");
}
所有绘图实体列表:link 1 (older) or link 2 (newer)
在this link中我们看到值为1的代码70是闭合折线。
并且在 this link 中我们看到这同样适用于折线 2d/3d,但另外使用值 8 我们定义它是 2d 还是 3d 折线。值可以按位组合,因此 8|1 表示封闭的 3d 折线。