• cad.net 封装jig


    重构了一下自己的几处jig代码,发现可以抽象出一些公共内容,不单纯每次写类继承(麻烦),
    提供出来给大家.

    #if !HC2020
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.EditorInput;
    using Autodesk.AutoCAD.Geometry;
    using Autodesk.AutoCAD.GraphicsInterface;
    using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
    #else
    using GrxCAD.DatabaseServices;
    using GrxCAD.EditorInput;
    using GrxCAD.Geometry;
    using GrxCAD.GraphicsInterface;
    using Acap = GrxCAD.ApplicationServices.Application;
    #endif
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    /*  封装jig
     *  20211216 加入块表时候做一个差集,剔除临时图元
     *  20211209 补充正交变量设置和回收设置
     *  作者: 惊惊⎛⎝◕⏝⏝◕。⎠⎞ ⎛⎝≥⏝⏝0⎠⎞ ⎛⎝⓿⏝⏝⓿。⎠⎞ ⎛⎝≥⏝⏝≤⎠⎞
     *  博客: https://www.cnblogs.com/JJBox/p/15650770.html
     *
     *  例子1:
     *  var ptjig = new Jig();
     *  ptjig.SetOptions(Point3d.Origin);
     *  var pr = ptjig.Drag();
     *  if (pr.Status != PromptStatus.OK)
     *      return null;
     *
     *  例子2:
     *  var ppo1 = new PromptPointOptions(Environment.NewLine + "输入矩形角点1:<空格退出>")
     *  {
     *      AllowArbitraryInput = true,//任意输入
     *      AllowNone           = true //允许回车
     *  };
     *  var ppr1 = ed.GetPoint(ppo1);//用户点选
     *  if (ppr1.Status != PromptStatus.OK)
     *      return;
     *  var getPt = ppr1.Value;
     *
     *  var recEntityJig = new Jig((mousePoint, drawEntitys) => {
     *      #region 画柜子图形
     *      double length = Math.Abs(getPt.X - mousePoint.X);
     *      double high = Math.Abs(getPt.Y - mousePoint.Y);
     *      var ent = AddRecToEntity(Point3d.Origin, new Point3d(length, high, 0));
     *      drawEntitys.Add(ent);
     *      #endregion
     *  });
     *  recEntityJig.SetOptions("指定矩形角点:", new Dictionary<string, string>() { { "Z", "中间(Z)" } );
     *
     *  bool flag = true;
     *  while (flag)
     *  {
     *      var pr = recEntityJig.Drag();
     *      if (string.IsNullOrEmpty(pr.StringResult))//在无输入的时候会等于空
     *          flag = false;
     *      else
     *      {
     *          switch (pr.StringResult.ToUpper()) //注意cad保留 https://www.cnblogs.com/JJBox/p/10224631.html
     *          {
     *              case "Z":
     *                  ed.WriteMessage("\n您触发了z关键字");
     *                  break;
     *              case " ":
     *                  flag = false;//空格结束
     *                  break;
     *          }
     *      }
     *  }
     *  //开启事务之后,图元加入数据库
     *  db.Action(tr=>{
     *     recEntityJig.AddEntityToMsPs(tr);
     *  });
     */
    
    namespace JoinBox
    {
        public delegate void WorldDrawEvent(WorldDraw draw);
        public class Jig : DrawJig
        {
            #region 成员
            /// <summary>
            /// 事件:默认是图元刷新,其余的:亮显/暗显等等工作自由补充
            /// </summary>
            public event WorldDrawEvent WorldDrawEvent;
            /// <summary>
            /// 最后的鼠标点,用来确认长度
            /// </summary>
            public Point3d MousePointWcsLast;
            /// <summary>
            /// 最后的图元,用来生成
            /// </summary>
            public Entity[] Entitys => _drawEntitys.ToArray();
    
            List<Entity> _drawEntitys;//重复生成的图元,放在这里刷新
            Autodesk.AutoCAD.Geometry.Tolerance _tolerance;
            Action<Point3d, List<Entity>> _action;
            JigPromptPointOptions _options;
            const string _orthomode = "orthomode";
            bool _systemVariablesOrthomode = false; //正交修改
            #endregion
    
            #region 构造
            /// <summary>
            /// 在界面绘制图元
            /// </summary>
            /// <param name="action">
            /// 用来频繁执行的回调: <see langword="Point3d"/>鼠标点,<see langword="List"/>加入显示图元的容器
            /// </param>
            /// <param name="tolerance">鼠标移动的容差</param>
            public Jig(Action<Point3d, List<Entity>> action = null, double tolerance = 1e-6)
            {
                _action      = action;
                _tolerance   = new(tolerance, tolerance);
                _drawEntitys = new();
            }
            #endregion
    
            #region 方法
            /// <summary>
            /// 鼠标配置:基点
            /// </summary>
            /// <param name="basePoint">基点</param>
            /// <param name="msg">提示信息</param>
            /// <param name="cursorType">光标绑定</param>
            /// <param name="orthomode">正交开关</param>
            public JigPromptPointOptions SetOptions(Point3d basePoint,
                CursorType cursorType = CursorType.RubberBand,
                string msg = "点选第二点",
                bool orthomode = false)
            {
                if (orthomode && CadSystem.Getvar(_orthomode) != "1")
                {
                    CadSystem.Setvar(_orthomode, "1");//1正交,0非正交 //setvar: https://www.cnblogs.com/JJBox/p/10209541.html
                    _systemVariablesOrthomode = true;
                }
                var tmp = new JigPromptPointOptions(Environment.NewLine + msg)
                {
                    Cursor = cursorType,   //光标绑定
                    UseBasePoint = true,   //基点打开
                    BasePoint = basePoint, //基点设定
    
                    //用户输入控件:  由UCS探测用 | 接受三维坐标
                    UserInputControls =
                        UserInputControls.GovernedByUCSDetect |
                        UserInputControls.Accept3dCoordinates
                };
                _options = tmp;
                return _options;
            }
    
            /// <summary>
            /// 鼠标配置:提示信息,关键字
            /// </summary>
            public JigPromptPointOptions SetOptions(string msg, Dictionary<string, string> keywords = null)
            {
                var tmp = new JigPromptPointOptions(Environment.NewLine + msg)
                {
                    //用户输入控件:  由UCS探测用 | 接受三维坐标
                    UserInputControls =
                          UserInputControls.GovernedByUCSDetect |
                          UserInputControls.Accept3dCoordinates
                };
                if (keywords != null)
                    foreach (var item in keywords)
                        tmp.Keywords.Add(item.Key, item.Key, item.Value);
    
                tmp.Keywords.Add(" ", " ", "<空格退出>"); //要放最后,才能优先触发其他关键字
                _options = tmp;
                return _options;
            }
    
            /// <summary>
            /// 鼠标配置:自定义
            /// </summary>
            /// <param name="action"></param>
            public void SetOptions(Action<JigPromptPointOptions> action)
            {
                var tmp = new JigPromptPointOptions();
                action.Invoke(tmp);
                _options = tmp;
            }
    
            /// <summary>
            /// 执行
            /// </summary>
            /// <returns></returns>
            public PromptResult Drag()
            {
                //jig功能必然是当前前台文档,所以封装内部更好调用
                var dm = Acap.DocumentManager;
                var doc = dm.MdiActiveDocument;
                var ed = doc.Editor;
                var dr = ed.Drag(this);
                if (_systemVariablesOrthomode)
                    CadSystem.Setvar(_orthomode, "0");//1正交,0非正交 //setvar: https://www.cnblogs.com/JJBox/p/10209541.html
                return dr;
            }
    
            /// <summary>
            /// 最后一次的图元加入数据库
            /// </summary>
            /// <param name="tr">事务</param>
            /// <param name="removeEntity">不生成的图元用于排除,例如刷新时候的提示文字</param>
            /// <returns></returns>
            public IEnumerable<ObjectId> AddEntityToMsPs(Transaction tr,
                IEnumerable<Entity> removeEntity = null)
            {
                var dm = Acap.DocumentManager;
                var doc = dm.MdiActiveDocument;
                var db = doc.Database;
                var ids = new List<ObjectId>();
                IEnumerable<Entity> ents = Entitys;
                if (removeEntity != null)
                    ents = Entitys.Except(removeEntity);
                foreach (var item in ents)
                    ids.Add(tr.AddEntityToMsPs(db, item));// https://www.cnblogs.com/JJBox/p/14300098.html
                return ids;
            }
            #endregion
    
            #region 重写
            /// <summary>
            /// 鼠标频繁采点
            /// </summary>
            /// <param name="prompts"></param>
            /// <returns>返回状态:令频繁刷新结束</returns>
            protected override SamplerStatus Sampler(JigPrompts prompts)
            {
                if (_options == null)
                    throw new ArgumentNullException(nameof(_options));
    
                var pro = prompts.AcquirePoint(_options);
                if (pro.Status == PromptStatus.Keyword)
                    return SamplerStatus.OK;
                if (pro.Status != PromptStatus.OK)
                    return SamplerStatus.Cancel;
    
                //上次鼠标点不同(一定要这句,不然图元刷新太快会看到奇怪的边线)
                var mousePointWcs = pro.Value;
    
                //==        是比较新建类的哈希值,
                //IsEqualTo 是方形判断(仅加法),
                //Distance  是圆形判断(会求平方根,使用了牛顿迭代),
                //一定要有这样细微的心,不然在大量数据(十万以上/频繁刷新)面前会显得非常慢.
                if (mousePointWcs.IsEqualTo(MousePointWcsLast, _tolerance))
                    return SamplerStatus.NoChange;
    
                //上次循环的缓冲区图元清理,否则将会在vs输出遗忘 Dispose
                foreach (var item in _drawEntitys)
                    item.Dispose();
                _drawEntitys.Clear();
    
                //委托把容器扔出去接收新创建的图元,然后给重绘更新
                _action?.Invoke(mousePointWcs, _drawEntitys);
    
                MousePointWcsLast = mousePointWcs;
                return SamplerStatus.OK;
            }
    
            /// <summary>
            /// 重绘图形
            /// </summary>
            protected override bool WorldDraw(WorldDraw draw)
            {
                if (_drawEntitys.Count != 0)
                {
                    //重绘是UI异步线程,所以必须生成一份副本
                    var lst = _drawEntitys.ToArray();
                    foreach (var item in lst)
                        draw.Geometry.Draw(item);
                }
    
                WorldDrawEvent?.Invoke(draw);
                return true;
            }
            #endregion
        }
    }
    

    (完)

  • 相关阅读:
    28335外部中断的简单介绍和配置
    C++中强制类型转换
    GitHub上Markdown语法的高级应用
    C++中强制类型转换
    模拟鼠标点击事件
    clone一行div tr 每次增量赋值
    linux tomcat自动部署shell
    maven 引用本地jar
    JDK自带工具keytool生成ssl证书
    jenkins+maven+svn实现简单的一键发布
  • 原文地址:https://www.cnblogs.com/JJBox/p/15650770.html
Copyright © 2020-2023  润新知