窗交选择——c#
在 AutoCAD 的 .NET API 中, SelectCrossingPolygon 方法属于 Editor 类(位于 Autodesk.AutoCAD.EditorInput 命名空间),其选择逻辑 完全基于实体的几何坐标,并与当前视图范围(显示区域)有关。以下是基于 .NET API 的详细分析:
1. 关键类与方法
.NET API 中的选择方法
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.DatabaseServices;
// 获取当前文档和编辑器
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Editor acEd = acDoc.Editor;
// 定义交叉多边形顶点(世界坐标系)
Point3dCollection vertexPoints = new Point3dCollection();
vertexPoints.Add(new Point3d(0, 0, 0));
vertexPoints.Add(new Point3d(10, 0, 0));
vertexPoints.Add(new Point3d(10, 10, 0));
vertexPoints.Add(new Point3d(0, 10, 0));
// 执行交叉多边形选择(Crossing 模式:包含或相交的实体被选中)
PromptSelectionResult selectionResult = acEd.SelectCrossingPolygon(vertexPoints);
if (selectionResult.Status == PromptStatus.OK)
{
SelectionSet selectionSet = selectionResult.Value;
// 处理选择集...
}
3. .NET API 与 COM API 的区别
- COM API:早期通过 ModelSpace.Select 等方法操作,逻辑类似,但 .NET API 更推荐使用 Editor 类的选择方法(如 SelectCrossingPolygon ),功能更统一且易于处理用户交互。
4. 坐标系与顶点定义
- 交叉多边形的顶点坐标使用 当前空间的坐标系(模型空间为世界坐标系,图纸空间为图纸坐标系),需确保顶点坐标与实体坐标在同一空间中计算。
- 若实体位于块或外部参照中,需先转换其局部坐标到世界坐标系,再定义多边形顶点。
经验证,实体在视图范围外(如极远坐标或被缩放/平移隐藏),窗交可能会失败。
public void 创建pointd点窗交()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
//var cur = db.SelectCurve("选择多段线");
//if (cur is null) return;
获取窗交对象
提取cur顶点
//if (!(cur is Polyline polyline)) return;
Point3dCollection pts = new Point3dCollection();
//for (int i = 0; i < polyline.NumberOfVertices; i++)
//{
//pts.Add(new Point3d(0,0,0));
//pts.Add(new Point3d(1000, 0, 0));
//pts.Add(new Point3d(1000, 1000, 0));
//pts.Add(new Point3d(0, 1000, 0));
// 计算并添加 1000 个点
int pointCount = 1000;
Point3d center = new Point3d(1000, 1000, 0); // 圆心
double radius = 1000; // 半径
for (int i = 0; i < pointCount; i++)
{
double angle = 2 * Math.PI * i / pointCount;
double x = center.X + radius * Math.Cos(angle);
double y = center.Y + radius * Math.Sin(angle);
double z = center.Z;
Point3d point = new Point3d(x, y, z);
pts.Add(point);
}
//pts.Add(polyline.GetPoint2dAt(i).toPoint3d());
//}
//获取窗交对象
PromptSelectionResult psr = ed.SelectCrossingPolygon(pts);
//判断窗交是否成功
if (psr.Status != PromptStatus.OK)
{
ed.WriteMessage("窗交失败");
return;
}
var ss = psr.Value;
var ids = ss.GetObjectIds();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 获取当前数据库的块表记录
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
// 获取模型空间块表记录
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
// 获取当前数据库的图形对象 闭合多段线 直线转多段线
foreach (var id in ids)
{
// 以写模式打开实体
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
entity.UpgradeOpen();
entity.ColorIndex =2;
}
tr.Commit();
}
}
public static Curve SelectCurve(this Database db, string message)
{
Curve curve = null;
Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
// 提示用户选择一条曲线
PromptEntityOptions peo = new PromptEntityOptions(message);
peo.SetRejectMessage("
所选对象不是曲线,请重新选择。");
peo.AddAllowedClass(typeof(Curve), false);
PromptEntityResult per = editor.GetEntity(peo);
if (per.Status == PromptStatus.OK)
{
//Database db = HostApplicationServices.WorkingDatabase;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
curve = (Curve)per.ObjectId.GetObject(OpenMode.ForRead);
}
}
return curve;
}
验证建议:通过代码在视图外创建实体并执行选择,检查 SelectionSet.Count 是否包含目标实体,即可确认逻辑正确性。