brainstorm 发表于 2020-10-18 23:55:21

Jig学习---通用Jig

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using ZgxCommomLib;


namespace test
{
    //委托类
    public delegate void DelChangeEntity(Entity ent, Point3d frompt, Point3d movetopt);
    public delegate Matrix3d DelSetMat(Point3d frompt, Point3d topt, double angle);
    public class ClassCommand
    {
      
      public void test()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = Application.DocumentManager.MdiActiveDocument.Database;
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            PromptSelectionResult psr = ed.GetSelection();
            SelectionSet ss = psr.Value;
            PromptPointResult ppr = ed.GetPoint("\n 选择点");
            Point3d ptBase = ppr.Value;
            ptBase = ptBase.TransformBy(ed.CurrentUserCoordinateSystem);

            //实体变换委托
            void del1(Entity ent, Point3d pt, Point3d moveform)
            {
                using (OpenCloseTransaction tr = db.TransactionManager.StartOpenCloseTransaction())
                {
                  tr.GetObject(ent.ObjectId, OpenMode.ForWrite, false);
                  if (ent is DBText)
                        ((DBText)ent).TextString = pt.ToString();
                  else if (ent is MText)
                        ((MText)ent).Contents = pt.ToString();
                  tr.Commit();
                }
            }

            //变换矩阵委托
            Matrix3d mat(Point3d ptFrom, Point3d ptTo, double angle)
            {
                //angle = 100.02;
                return Matrix3d.Displacement(ptFrom.GetVectorTo(ptTo));
            }

            DelSetMat setMat = new DelSetMat(mat);
            DelChangeEntity changeEntity = new DelChangeEntity(del1);

            //通过类实例化jig
            DelDrawJig delJig = DrawJigEntrance.EnterJig(changeEntity, setMat, true, true);

            int iControlFlag = (int)(UserInputControls.Accept3dCoordinates |
                   UserInputControls.NoZeroResponseAccepted |
                   UserInputControls.NoNegativeResponseAccepted |
                   UserInputControls.NullResponseAccepted);

            delJig.AddEntity(ss);
            delJig.BasePnt = ptBase;
            delJig.Movefrom = ptBase;
            delJig.MoveEndPnt = ptBase;
            delJig.PrmpStr = "\n移动到";
            delJig.KeyString = "A_A旋转;S_S左右镜像;D_D重新选点;F_F图取标高值<退出>";
            delJig.CursorType = (int)CursorType.Crosshair;
            delJig.ControlFlag = iControlFlag;

            using (delJig)
            {
                try
                {

                  //事务管理器
                  using (Transaction trans = db.TransactionManager.StartTransaction())
                  {
                        // Draw Jig 交互
                        PromptResult pr;
                        pr = ed.Drag(delJig);
                        // 结果
                        if (pr.Status == PromptStatus.OK)
                        {
                            delJig.TransFormEntities();
                            trans.Commit();
                            ed.WriteMessage("\n 拖拽结束");
                            return;
                        }
                        else
                            trans.Abort();
                  }// end of using tr1

                }//end of try
                catch (System.Exception ex)
                {
                  ed.WriteMessage("\nJig出错了");
                  ed.WriteMessage("\ncatch" + ex.Message);
                  //Application.SetSystemVariable("orthomode", orthomode);
                  return;
                }
            }// end of using Jig
      }

    }
    public class DrawJigEntrance
    {
      public static DelDrawJig EnterJig(DelChangeEntity changeEntity, DelSetMat acquireMat)
      {
            return new DelDrawJig(changeEntity, acquireMat);
      }

      public static DelDrawJig EnterJig(DelChangeEntity changeEntity, DelSetMat setMat, bool useMat)
      {
            DelDrawJig del = new DelDrawJig(changeEntity, setMat);
            del.Usepushmat = useMat;
            return del;
      }

      public static DelDrawJig EnterJig(DelChangeEntity changeEntity, DelSetMat setMat, bool useMat, bool useBasePoint)
      {
            DelDrawJig del = new DelDrawJig(changeEntity, setMat);
            del.Usepushmat = useMat;
            del.Userbasept = useBasePoint;
            return del;
      }
    }

    public class DelDrawJig : DrawJig, IDisposable
    {
      #region 字段

      private Document doc = Application.DocumentManager.MdiActiveDocument;
      private Database db = Application.DocumentManager.MdiActiveDocument.Database;
      private Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

      private Matrix3d _mat;//变换矩阵
      private List<Entity> _entities = new List<Entity>();
      private string _Callback;//回调函数名称
                                 //private ResultBuffer _RbInvoke;//回调函数resultbuffer
      private ResultBuffer _lsprtn;//回调lisp返回值

      private string _PrmpStr;//提示字符串
                              //关键字格式:
                              //"A_A旋转;S_S左右镜像;D_D重新选点;F_F图取标高值<退出>"
      private string _KeyString;//允许关键字
      private int _CursorType;//光标类型
      private int _ControlFlag;//采样允许输入类型
      private string _RtnKeyString;//返回关键字,

      private Point3d _BasePnt;//基点
      private Point3d _movefrom;//出发点
      private Point3d _moveto;//目标点

      private bool _UseBasePt = true;//是否使用基点
      private bool _UsePushMat = true;//是否使用矩阵

      private DelChangeEntity _changentity;//委托方法1   
      private DelSetMat _acquireMat;//委托方法2

      #endregion 字段

      #region 属性
      //lisp回调函数名称
      public string CallBack
      {
            get { return _Callback; }
            set { _Callback = value; }
      }
      //移动点
      public Point3d MoveEndPnt
      {
            get { return _moveto; }
            set { _moveto = value; }
      }
      public Point3d BasePnt
      {
            get { return _BasePnt; }
            set { _BasePnt = value; }
      }
      public string PrmpStr
      {
            get { return _PrmpStr; }
            set { _PrmpStr = value; }
      }
      public string KeyString
      {
            get { return _KeyString; }
            set { _KeyString = value; }
      }
      public int CursorType
      {
            get { return _CursorType; }
            set { _CursorType = value; }
      }
      public int ControlFlag
      {
            get { return _ControlFlag; }
            set { _ControlFlag = value; }
      }

      public List<Entity> Entities { get => _entities; set => _entities = value; }
      public ResultBuffer Lsprtn { get => _lsprtn; set => _lsprtn = value; }
      public Matrix3d Mat { get => _mat; set => _mat = value; }
      public bool Userbasept { get => _UseBasePt; set => _UseBasePt = value; }
      public bool Usepushmat { get => _UsePushMat; set => _UsePushMat = value; }
      public string RtnKeyString { get => _RtnKeyString; set => _RtnKeyString = value; }
      public Point3d Movefrom { get => _movefrom; set => _movefrom = value; }
      public DelChangeEntity Changentity
      {
            get { return _changentity; }
            set { _changentity = value; }
      }
      public DelSetMat AcquireMat
      {
            get { return _acquireMat; }
            set { _acquireMat = value; }
      }

      #endregion 属性

      #region 方法

      public DelDrawJig()
      {
      }
      public DelDrawJig(DelChangeEntity delChangeEntity, DelSetMat acquireMat)
      {
            _changentity = delChangeEntity;//委托方法1   
            _acquireMat = acquireMat;//委托方法2
      }
      public DelDrawJig(ResultBuffer rb)
      {
            using (rb)
            {
                if (rb == null)
                  return;
                //初始化数值
                TypedValue[] tb = rb.AsArray();
                _Callback = (string)tb.Value;//回调函数            
                _PrmpStr = (string)tb.Value;//提示符
                _KeyString = (string)tb.Value;//关键字
                _ControlFlag = Convert.ToInt32(tb.Value);//光标控制
                _CursorType = Convert.ToInt32(tb.Value);//光标
                _BasePnt = (Point3d)tb.Value; //基点
                                                 //_ob = rb;
            }
      }

      public void DyndrawRedefine(ResultBuffer rb)
      {
            using (rb)
            {
                if (rb == null)
                  return;
                //初始化数值
                TypedValue[] tb = rb.AsArray();
                _Callback = (string)tb.Value;//回调函数            
                _PrmpStr = (string)tb.Value;//提示符
                _KeyString = (string)tb.Value;//关键字
                _ControlFlag = Convert.ToInt32(tb.Value);//光标控制
                _CursorType = Convert.ToInt32(tb.Value);//光标
                _BasePnt = (Point3d)tb.Value; //基点   
            }
      }

      public void AddEntity(Entity ent)
      {

            Entities.Add(ent);
      }
      public void AddEntity(ObjectId[] ids)
      {
            OpenCloseTransaction trans = db.TransactionManager.StartOpenCloseTransaction();
            using (trans)
            {
                foreach (ObjectId id in ids)
                {
                  Entity ent = trans.GetObject(id, OpenMode.ForRead) as Entity;
                  AddEntity(ent);
                }
                trans.Commit();
            }
      }
      public void AddEntity(SelectionSet ss)
      {
            ObjectId[] ids = ss.GetObjectIds();
            AddEntity(ids);
      }

      public void TransFormEntities()
      {
            OpenCloseTransaction trans = db.TransactionManager.StartOpenCloseTransaction();
            using (trans)
            {
                foreach (Entity ent in Entities)
                {
                  trans.GetObject(ent.ObjectId, OpenMode.ForWrite, false);// as Entity;
                  ent.TransformBy(_mat);
                  trans.Commit();
                }
            }
      }
      #endregion 方法


      protected override SamplerStatus Sampler(JigPrompts prompts)
      {

            JigPromptPointOptions prOptions1 = new JigPromptPointOptions(_PrmpStr);
            prOptions1.PpoFromString(_KeyString);
            prOptions1.UserInputControls = (UserInputControls)_ControlFlag;
            prOptions1.BasePoint = _BasePnt;
            prOptions1.UseBasePoint = _UseBasePt;
            prOptions1.Cursor = (CursorType)_CursorType;
            PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
            _movefrom = _moveto;
            //_BasePnt = _moveto;
            if (prResult1.Status == PromptStatus.Keyword)
            {
                _RtnKeyString = prResult1.StringResult;
                return SamplerStatus.OK;
            }
            if (prResult1.Status != PromptStatus.OK)
                return SamplerStatus.Cancel;

            if (prResult1.Value.Equals(_moveto))
            {
                return SamplerStatus.NoChange;
            }
            else
            {

                _moveto = prResult1.Value;//;.TransformBy(ed.CurrentUserCoordinateSystem);
                return SamplerStatus.OK;
            }
      }

      protected override bool WorldDraw(WorldDraw draw)
      {
            WorldGeometry geo = draw.Geometry;
            if (geo != null)
            {
                try
                {
                  if (_UsePushMat == true)
                  {
                        _mat = _acquireMat(_BasePnt, _moveto, 30.0);//委托2
                        geo.PushModelTransform(_mat);
                        foreach (Entity ent in _entities)
                        {
                            if (_changentity != null)
                              _changentity(ent, _movefrom, _moveto);//委托1
                            ent.RecordGraphicsModified(true);
                            geo.Draw(ent);


                        }
                        geo.PopModelTransform();
                  }
                  else
                  {
                        //_mat = _acquireMat(_BasePnt, _moveto, 30.0);//委托2
                        //geo.PushModelTransform(_mat);
                        foreach (Entity ent in _entities)
                        {
                            if (_changentity != null)
                              _changentity(ent, _movefrom, _moveto);//委托1
                            ent.RecordGraphicsModified(true);
                            geo.Draw(ent);


                        }
                        //geo.PopModelTransform();
                  }
                }
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                  ed.WriteMessage(ex.ToString());
                }
            }// if geo
            return false;
      }// end of override bool WorldDraw
      #region IDisposable Support
      private bool disposedValue = false; // 要检测冗余调用

      protected virtual void Dispose(bool disposing)
      {
            if (!disposedValue)
            {
                if (disposing)
                {
                  //foreach (FieldInfo info in typeof(DynDraw).GetFields())
                  //{
                  //    Doc.Editor.WriteMessage("\n正在显示:" + info.ToString());

                  //}
                  Entities = null;
                  //_RbInvoke.Dispose();
                  Lsprtn = null;
                  _KeyString = null;
                  doc = null;
                  db = null;

                  //_Drawent = null;

                  // TODO: 释放托管状态(托管对象)。
                }

                // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
                // TODO: 将大型字段设置为 null。

                disposedValue = true;
            }
      }

      // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
      // ~DynDraw() {
      //   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
      //   Dispose(false);
      // }

      // 添加此代码以正确实现可处置模式。
      public void Dispose()
      {
            // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
            Dispose(true);
            // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
            // GC.SuppressFinalize(this);
      }
      #endregion
    }
}

lxw320 发表于 2020-10-19 08:45:23

学习一下各位的思路

carrot1983 发表于 2020-10-26 23:03:46

看了很多代码,还是没有搞懂,楼主的代码需要再花很多时间消化。关于.net一直没有找到很完整的学习手册。才鸟的书,关于jig的内容也只是蜻蜓点水。
比如:RecordGraphicsModified 这是干嘛的??
半路出家,一头雾水。

666SHUN 发表于 2021-3-31 09:27:37

本帖最后由 666SHUN 于 2021-3-31 09:29 编辑

楼主你好,这个通用JIG怎样调用呢?比如我自己写的程序,插入一个块,就像实现和CAD一样,可以动态看到块,现在没用JIG,啥也看不到,只有插入后才看见。看到你using ZgxCommomLib;这个,这是自己的库嘛

d1742647821 发表于 2023-2-10 11:21:39

666SHUN 发表于 2021-3-31 09:27
楼主你好,这个通用JIG怎样调用呢?比如我自己写的程序,插入一个块,就像实现和CAD一样,可以动态看到块, ...

可以尝试使用ifox
页: [1]
查看完整版本: Jig学习---通用Jig