窗交选择(跳过自己本身)——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("\n所选对象不是曲线,请重新选择。");
      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;
  }

  using (var tr = db.TransactionManager.StartTransaction())
  {
      foreach (SelectedObject so in sset)
      {
          if (so != null && so.ObjectId != blockidfirst)//跳过空和自己
          {
              var cur = tr.GetObject(so.ObjectId, OpenMode.ForRead) as Curve;
              if (Math.Abs(cur.Area - 一个参照物.Area) > 0.01 * 一个参照物.Area) continue;
              A的候选们.Add(cur);
              #region
              //cur.Highlight();
              //判断图层是否相同
              //if (cur.Layer == layer)
              //{
              //    克隆图形
              //    //var clone = cur.Clone() as Curve;
              //    //if (clone == null) continue;
              //    插入块
              //    //blockidfirst.InsertBlock(cur.GeometricExtents.CenterPoint(), 0, new Scale3d(1, 1, 1));
              //    添加到模型空间
              //    //Z.eAddtoMS(clone);
              //}
              #endregion
              
          }
      }
      tr.Commit();
  }

验证建议:通过代码在视图外创建实体并执行选择,检查  SelectionSet.Count  是否包含目标实体,即可确认逻辑正确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值