选中图框 计算图框边界 添加选中效果

68 阅读1分钟
[CommandMethod("TestSelects")]

  public void TestSelect()

  {

      doc = Application.DocumentManager.MdiActiveDocument;

      ed = doc.Editor;

      db = doc.Database;

  


      var filter = new SelectionFilter(new TypedValue[]

      {

          new TypedValue((int)DxfCode.Start, "INSERT"),

      });

  


      var result = ed.GetSelection(filter);

  


      if (result.Status == PromptStatus.OK)

      {

          SelectedBlockIds = result.Value.GetObjectIds().ToList();

          ed.WriteMessage($"\n已选中 {SelectedBlockIds.Count} 个图框,开始分析...");

          AnalyzeAndMarkFrames();

      }

      else

      {

          SelectedBlockIds.Clear();

          ed.WriteMessage("\n未选中任何图框。");

      }

  }
  
  private void AnalyzeAndMarkFrames()

{

    ValidFrameIds.Clear();

    frameCounter = 1;

  


    using (Transaction tr = db.TransactionManager.StartTransaction())

    {

        try

        {

            BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

            foreach (ObjectId blockId in SelectedBlockIds)

            {

                Entity entity = tr.GetObject(blockId, OpenMode.ForWrite) as Entity;

                if (entity == null) continue;

  


                BlockReference blockRef = entity as BlockReference;

                if (blockRef == null) continue; // 不是块参照就跳过

  


                // 1. 直接高亮图框实体

                blockRef.ColorIndex = 1; // 设置为红色

  


                // 2. 在图框中心添加编号

                AddFrameNumber(blockRef, frameCounter, tr, modelSpace);

  


                ValidFrameIds.Add(blockId);

                frameCounter++;

            }

            tr.Commit();

            ed.WriteMessage($"\n共标记了 {ValidFrameIds.Count} 个有效图框");

        }

        catch (Autodesk.AutoCAD.Runtime.Exception ex)

        {

            ed.WriteMessage($"\n分析过程中发生错误: {ex.Message}");

            tr.Abort();

        }

    }

}


// 新增一个专门用于添加编号的方法

  private void AddFrameNumber(BlockReference blockRef, int number, Transaction tr, BlockTableRecord modelSpace)

  {

      try

      {

          // 获取块定义中的边界线实体(忽略文字等其他实体)

          Extents3d? frameExtents = GetFrameBoundary(blockRef, tr);

                

          if (!frameExtents.HasValue)

          {

              // 如果无法获取边界线,使用块参照的几何边界作为备选

              frameExtents = blockRef.GeometricExtents;

          }

                

          Extents3d ext = frameExtents.Value;

                

          // 计算实体的尺寸

          double entityHeight = ext.MaxPoint.Y - ext.MinPoint.Y;

                

          // 文字高度等于图框的高度

          double textHeight = entityHeight;

                

          // 计算文字位置 - 使用中心点

          Point3d center = ext.MinPoint + (ext.MaxPoint - ext.MinPoint) / 2.0;

  


          // 创建文字编号

          DBText text = new DBText

          {

              TextString = number.ToString(),

              Position = center,

              Height = textHeight,

              HorizontalMode = TextHorizontalMode.TextCenter,

              VerticalMode = TextVerticalMode.TextVerticalMid,

              AlignmentPoint = center,

              ColorIndex = 1 // 红色

          };

                

          // 创建图框边界矩形

          Polyline rectangle = new Polyline();

          rectangle.AddVertexAt(0, new Point2d(ext.MinPoint.X, ext.MinPoint.Y), 0, 0, 0);

          rectangle.AddVertexAt(1, new Point2d(ext.MaxPoint.X, ext.MinPoint.Y), 0, 0, 0);

          rectangle.AddVertexAt(2, new Point2d(ext.MaxPoint.X, ext.MaxPoint.Y), 0, 0, 0);

          rectangle.AddVertexAt(3, new Point2d(ext.MinPoint.X, ext.MaxPoint.Y), 0, 0, 0);

          rectangle.Closed = true;

          rectangle.ColorIndex = 2; // 黄色

          rectangle.LineWeight = LineWeight.LineWeight050; // 设置线宽

                

          ZoomToPoint(ed, center);

                

          // 添加矩形和文字到模型空间

          modelSpace.AppendEntity(rectangle);

          tr.AddNewlyCreatedDBObject(rectangle, true);

          CreatedMarkingIds.Add(rectangle.ObjectId); // 记录矩形ID

                

          modelSpace.AppendEntity(text);

          tr.AddNewlyCreatedDBObject(text, true);

          CreatedMarkingIds.Add(text.ObjectId); // 记录文字ID

      }

      catch (Autodesk.AutoCAD.Runtime.Exception ex)

      {

          ed.WriteMessage($"\n添加编号时出错: {ex.Message}");

      }

  }
  
  private Extents3d? GetFrameBoundary(BlockReference blockRef, Transaction tr)

     {

         try

         {

             BlockTableRecord blockDef = (BlockTableRecord)tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead);

             Extents3d? frameExtents = null;

             Matrix3d transform = blockRef.BlockTransform;

                

             foreach (ObjectId objId in blockDef)

             {

                 Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;

                 if (ent != null)

                 {

                     // 只处理边界线实体:Polyline, Line, Circle, Arc, Rectangle等

                     if (ent is Polyline || ent is Line || ent is Circle || ent is Arc || 

                         ent is Ellipse || ent is Spline || ent is Region)

                     {

                         try

                         {

                             // 获取实体在块定义空间的边界

                             Extents3d entExtents = ent.GeometricExtents;

                                

                             // 变换到世界坐标系

                             Point3d minPt = entExtents.MinPoint.TransformBy(transform);

                             Point3d maxPt = entExtents.MaxPoint.TransformBy(transform);

                                

                             Extents3d transformedExtents = new Extents3d(minPt, maxPt);

                                

                             if (frameExtents == null)

                                 frameExtents = transformedExtents;

                             else

                             {

                                 Extents3d current = frameExtents.Value;

                                 current.AddExtents(transformedExtents);

                                 frameExtents = current;

                             }

                         }

                         catch { /* 忽略无法获取边界的实体 */ }

                     }

                 }

             }

                

             return frameExtents;

         }

         catch

         {

             return null;

         }

     }