wang2006zhi 发表于 2025-2-14 12:28:49

交互类的封装

本帖最后由 wang2006zhi 于 2025-2-14 12:30 编辑

using HTJ.Arx.Service.Imp;

namespace HTJ.Arx;

public static class EditEx
{
    /// <summary>
    ///   以单点(中心点)构造选择点集
    /// </summary>
    /// <param name="cenpt">中心单点3D</param>
    /// <param name="ex">偏移量</param>
    /// <returns>点集合</returns>
    public static Point3dCollection GetPointCollection(this Point3d cenpt, double ex = 1e-3)
    {
      return new Point3dCollection
      {
            new Point3d(cenpt.X - 0.5 * ex, cenpt.Y - 0.5 * ex, 0),
            new Point3d(cenpt.X + 0.5 * ex, cenpt.Y - 0.5 * ex, 0),
            new Point3d(cenpt.X + 0.5 * ex, cenpt.Y + 0.5 * ex, 0),
            new Point3d(cenpt.X - 0.5 * ex, cenpt.Y + 0.5 * ex, 0)
      };
    }

    /// <summary>
    ///   以单点(中心点)构造选择点集
    /// </summary>
    /// <param name="cenpt">中心单点2D</param>
    /// <param name="ex">偏移量</param>
    /// <returns>点集合</returns>
    public static Point3dCollection GetPointCollection(this Point2d cenpt, double ex = 1e-3)
    {
      return GetPointCollection(cenpt.Point3d(), ex);
    }


    /// <summary>
    ///   单点(左下角)构造选择点集
    /// </summary>
    /// <param name="minpt">二维点</param>
    /// <param name="width">宽度</param>
    /// <param name="height">高度</param>
    /// <returns>四个角点组成的点集</returns>
    public static Point3dCollection GetPointCollection(this Point2d minpt, double width, double height)
    {
      return new Point3dCollection
      {
            new Point3d(minpt.X, minpt.Y, 0),
            new Point3d(minpt.X + width, minpt.Y, 0),
            new Point3d(minpt.X + width, minpt.Y + height, 0),
            new Point3d(minpt.X, minpt.Y + height, 0)
      };
    }

    /// <summary>
    ///   单点(左下角)构造选择点集
    /// </summary>
    /// <param name="minPt">三维点</param>
    /// <param name="width">宽度</param>
    /// <param name="height">高度</param>
    /// <returns>四个角点组成的点集</returns>
    public static Point3dCollection GetPointCollection(this Point3d minPt, double width, double height)
    {
      var pt2d = new Point2d(minPt.X, minPt.Y);
      return GetPointCollection(pt2d, width, height);
    }

    /// <summary>
    ///   两点构造选择点集
    /// </summary>
    /// <param name="ptA">三维点</param>
    /// <param name="ptB">三维点</param>
    /// <param name="ex">外扩距离</param>
    /// <returns>四个角点组成的点集</returns>
    public static Point3dCollection GetPointCollection(this Point3d ptA, Point3d ptB, double ex = 1e-3)
    {
      var minX = Math.Min(ptA.X, ptB.X) - ex;
      var minY = Math.Min(ptA.Y, ptB.Y) - ex;
      var maxX = Math.Max(ptA.X, ptB.X) + ex;
      var maxY = Math.Max(ptA.Y, ptB.Y) + ex;

      return new Point3dCollection
      {
            new Point3d(minX, minY, 0),
            new Point3d(maxX, minY, 0),
            new Point3d(maxX, maxY, 0),
            new Point3d(minX, maxY, 0)
      };
    }

    /// <summary>
    ///   两点构造选择点集
    /// </summary>
    /// <param name="ptA">二维点</param>
    /// <param name="ptB">二维点</param>
    /// <param name="ex">外扩距离</param>
    /// <returns>四个角点组成的点集</returns>
    public static Point3dCollection GetPointCollection(this Point2d ptA, Point2d ptB, double ex = 1e-3)
    {
      return ptA.Point3d().GetPointCollection(ptB.Point3d(), ex);
    }

    /// <summary>
    ///   外包构造选择点集
    /// </summary>
    /// <param name="box"></param>
    /// <param name="ex"></param>
    /// <returns></returns>
    public static Point3dCollection GetPointCollection(this BoundingInfo box, double ex = 1e-3)
    {
      var ext3d = box.Extents3d;
      var pt1 = ext3d.MinPoint;
      var pt2 = ext3d.MaxPoint;
      return pt1.GetPointCollection(pt2, ex);
    }

    /// <summary>
    ///   外包构造选择点集
    /// </summary>
    /// <param name="ext3d"></param>
    /// <param name="ex"></param>
    /// <returns></returns>
    public static Point3dCollection GetPointCollection(this Extents3d ext3d, double ex = 1e-3)
    {
      var pt1 = ext3d.MinPoint;
      var pt2 = ext3d.MaxPoint;
      return pt1.GetPointCollection(pt2, ex);
    }

    /// <summary>
    ///   Rect造选择点集
    /// </summary>
    /// <param name="rect"></param>
    /// <param name="ex"></param>
    /// <returns></returns>
    public static Point3dCollection GetPointCollection(this Rect rect, double ex = 1e-3)
    {
      return rect.MinPoint.GetPointCollection(rect.MaxPoint, ex);
    }

    public static Point3dCollection GetPointCollection(this RectAngEx.RectAng rectAng, double ex = 1e-3)
    {
      var newRectAng = rectAng.Expand(ex);
      var pts = newRectAng.ToPoints();
      var nptc = new Point3dCollection();
      for (var i = pts.Length - 1; i >= 0; i--)
      {
            var pt = pts.Point3d();
            nptc.Add(pt);
      }

      return nptc;
    }

    /// <summary>
    ///   获取矩阵变换(平移,缩放,旋转)后的点集
    /// </summary>
    /// <param name="ptColl">原始点集</param>
    /// <param name="mat">矩阵变量</param>
    /// <returns>返回变换后的点集</returns>
    public static Point3dCollection TransformBy(this Point3dCollection ptColl, Matrix3d mat)
    {
      var nptc = new Point3dCollection();
      for (var i = ptColl.Count - 1; i >= 0; i--)
      {
            var pt = ptColl.TransformBy(mat);
            nptc.Add(pt);
      }

      return nptc;
    }

    /// <summary>
    ///   获取一个字符串
    /// </summary>
    /// <param name="ed"></param>
    /// <param name="str"></param>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static bool GetString(this Editor ed, out string str, string msg = "输入一个字符串:<空格退出>")
    {
      str = string.Empty;
      var pso = new PromptStringOptions(Environment.NewLine + msg)
      {
            AllowSpaces = true //允许空格
      };
      var pdr = ed.GetString(pso);
      if (pdr.Status != PromptStatus.OK)
            return false;
      str = pdr.StringResult;
      return true;
    }

    /// <summary>
    ///   获取一个实数
    /// </summary>
    /// <param name="ed"></param>
    /// <param name="value"></param>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static bool GetDouble(this Editor ed, out double value, string msg = "输入一个实数:<空格退出>")
    {
      value = 0.0;
      var pdo = new PromptDoubleOptions(Environment.NewLine + msg)
      {
            AllowArbitraryInput = true, //任意输入
            AllowNone = true //允许回车
      };
      var pdr = ed.GetDouble(pdo);
      if (pdr.Status != PromptStatus.OK)
            return false;
      value = pdr.Value;
      return true;
    }

    /// <summary>
    ///   获取下一个点
    /// </summary>
    /// <param name="ed">命令行</param>
    /// <param name="pt">获取的点</param>
    /// <param name="msg">提示</param>
    /// <returns></returns>
    public static bool GetPoint(this Editor ed, out Point3d pt, string msg = "指定一点:<空格退出>")
    {
      pt = new Point3d();
      var ppo = new PromptPointOptions(Environment.NewLine + msg)
      {
            AllowArbitraryInput = true, //任意输入
            AllowNone = true //允许回车
      };
      var ppr = ed.GetPoint(ppo);
      if (ppr.Status != PromptStatus.OK)
            return false;
      pt = ppr.Value;
      return true;
    }

    /// <summary>
    ///   获取下一个点
    /// </summary>
    /// <param name="ed">命令行</param>
    /// <param name="pt">获取的点</param>
    /// <param name="ptk">上一个点</param>
    /// <param name="msg">提示</param>
    /// <returns></returns>
    public static bool GetPoint(this Editor ed, out Point3d pt, Point3d ptk, string msg = "指定一点:<空格退出>")
    {
      pt = new Point3d();
      var ppr = ed.GetPoint(msg, ptk);
      if (ppr.Status != PromptStatus.OK)
            return false;
      pt = ppr.Value;
      return true;
    }

    /// <summary>
    ///   屏幕拾取实体列表
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="ed">命令行</param>
    /// <param name="ents">指定类型的List</param>
    /// <param name="msg">提示</param>
    /// <param name="fil">过滤条件,为空时候无条件</param>
    /// <returns>bool</returns>
    public static bool GetEnts<T>(this Editor ed,
      out List<T> ents,
      SelectionFilter? fil = null,
      string msg = "请选择对象:") where T : Entity
    {
      ents = new List<T>();
      var pso = new PromptSelectionOptions
      {
            MessageForAdding = Environment.NewLine + msg
      };
      var psr = ed.GetSelection(pso, fil);
      if (psr.Status != PromptStatus.OK)
            return false;
      ents = psr.Value.GetEntities<T>().ToList();
      return ents.Any();
    }

    /// <summary>
    ///   窗选模式获取取实体列表
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="ed">命令行</param>
    /// <param name="ents">指定类型的List</param>
    /// <param name="ptColl">点集合,为空时候全选模式</param>
    /// <param name="fil">过滤条件,为空时候无条件</param>
    /// <returns>bool</returns>
    public static bool SelEnts<T>(this Editor ed,
      out List<T> ents,
      Point3dCollection? ptColl = null,
      SelectionFilter? fil = null) where T : Entity
    {
      var psr = ptColl != null ? ed.SelectCrossingPolygon(ptColl, fil) : ed.SelectAll(fil);
      ents = new List<T>();
      if (psr.Status != PromptStatus.OK)
            return false;
      ents = psr.Value.GetEntities<T>().ToList();
      return ents.Count>0;
    }

    /// <summary>
    ///   点选获取单个实体
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="ed">命令行</param>
    /// <param name="t">实体</param>
    /// <param name="pt">返回点</param>
    /// <param name="isNested">块内</param>
    /// <param name="msg">提示</param>
    /// <returns>bool</returns>
    public static bool SelEnt<T>(this Editor ed,
      out T t,
      out Point3d pt,
      bool isNested = false,
      string msg = "请选择对象:") where T : Entity
    {
      t = null!;
      ObjectId id;
      if (isNested)
      {
            var pner = ed.GetNestedEntity(Environment.NewLine + msg);
            pt = pner.PickedPoint;
            if (pner.Status != PromptStatus.OK)
                return false;
            id = pner.ObjectId;
      }
      else
      {
            var per = ed.GetEntity(Environment.NewLine + msg);
            pt = per.PickedPoint;
            if (per.Status != PromptStatus.OK)
                return false;
            id = per.ObjectId;
      }

      if (id.GetObject<Entity>() is not T result)
            return false;
      t = result;
      return true;

    }

    /// <summary>
    ///   点选获取单个实体
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <param name="ed">命令行</param>
    /// <param name="t">实体</param>
    /// <param name="isNested">块内</param>
    /// <param name="msg">提示</param>
    /// <returns>bool</returns>
    public static bool SelEnt<T>(this Editor ed,
      out T t,
      bool isNested = false,
      string msg = "请选择对象:")
      where T : Entity
    {
      t = null!;
      ObjectId id;
      if (isNested)
      {
            var pner = ed.GetNestedEntity(Environment.NewLine + msg);
            if (pner.Status != PromptStatus.OK)
                return false;
            id = pner.ObjectId;
      }
      else
      {
            var per = ed.GetEntity(Environment.NewLine + msg);
            if (per.Status != PromptStatus.OK)
                return false;
            id = per.ObjectId;
      }

      if (id.GetObject<T>() is not { } result)
            return false;
      t = result;
      return true;
    }

   

    /// <summary>
    ///   点选获取单个实体Id
    /// </summary>
    /// <param name="ed"></param>
    /// <param name="id"></param>
    /// <param name="pt">返回点</param>
    /// <param name="tClass">RXClass类型</param>
    /// <param name="isNested">块内</param>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static bool SelId(this Editor ed,
      out ObjectId id,
      out Point3d pt,
      RXClass? tClass = null,
      bool isNested = false,
      string msg = "请选择对象:")
    {
      id = ObjectId.Null;
      pt = new Point3d();
      if (isNested)
      {
            var pner = ed.GetNestedEntity(Environment.NewLine + msg);
            if (pner.Status != PromptStatus.OK)
                return false;
            id = pner.ObjectId;
            pt = pner.PickedPoint;
      }
      else
      {
            var per = ed.GetEntity(Environment.NewLine + msg);
            if (per.Status != PromptStatus.OK) return false;
            id = per.ObjectId;
            pt = per.PickedPoint;
      }

      return tClass == null || id.IsDerivedFrom(tClass);
    }

    /// <summary>
    ///   点选获取单个实体Id
    /// </summary>
    /// <param name="ed"></param>
    /// <param name="id"></param>
    /// <param name="tClass">RXClass类型</param>
    /// <param name="isNested">块内</param>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static bool SelId(this Editor ed,
      out ObjectId id,
      RXClass? tClass = null,
      bool isNested = false,
      string msg = "请选择对象:")
    {
      id = ObjectId.Null;
      if (isNested)
      {
            var pner = ed.GetNestedEntity(Environment.NewLine + msg);
            if (pner.Status != PromptStatus.OK) return false;
            id = pner.ObjectId;
      }
      else
      {
            var per = ed.GetEntity(Environment.NewLine + msg);
            if (per.Status != PromptStatus.OK) return false;
            id = per.ObjectId;
      }

      return tClass == null || id.IsDerivedFrom(tClass);
    }


    /// <summary>
    ///   窗选模式获取取实体列表
    /// </summary>
    /// <param name="ed">命令行</param>
    /// <param name="ids">指定类型的List</param>
    /// <param name="tClass">RXClass类型</param>
    /// <param name="ptc">点集合,为空时候全选模式</param>
    /// <param name="fil">过滤条件,为空时候无条件</param>
    /// <returns>bool</returns>
    public static bool SelIds(this Editor ed,
      out List<ObjectId> ids,
      RXClass? tClass = null,
      Point3dCollection? ptc = null,
      SelectionFilter? fil = null)
    {
      var psr = ptc != null ? ed.SelectCrossingPolygon(ptc, fil) : ed.SelectAll(fil);
      ids = new List<ObjectId>();
      if (psr.Status != PromptStatus.OK)
            return false;
      ids = psr.Value.GetObjectIds().ToList();
      if (tClass != null)
            ids = ids.Where(id => id.IsDerivedFrom(tClass)).ToList();
      return ids.Count>0;
    }
}

Bao_lai 发表于 2025-2-14 21:23:24

要得,感谢分享~

箭头_Row 发表于 2025-2-17 21:45:07

本帖最后由 箭头_Row 于 2025-2-17 22:38 编辑

儘量不要用PointColliction的容器,這個容器得手動去釋放或加using,無法做到像List<Point>容器一樣自動GC回收,如果要傳入桌子函數形參時可以再轉換為PointColliction的容器!
页: [1]
查看完整版本: 交互类的封装