当前位置: 首页 > article >正文

034集——JIG效果实现(橡皮筋效果)(CAD—C#二次开发入门)

可实现效果如下(对象捕捉F3需打开,否则效果不好):

   public class CircleJig : EntityJig
   {
       public static void DraCJig()
       {
           PromptPointResult ppr = Z.ed.GetPoint("a");
           if (ppr.Value == null) return;
           Point3d pt = ppr.Value;
           CircleJig circle = new CircleJig(pt);
           Polyjig poly = new Polyjig(pt);
           for (; ; )
           {
               PromptResult resJig = Z.ed.Drag(circle);//拖动圆
               if (resJig.Status == PromptStatus.Cancel)
               {
                   return;
               }
              
               if (resJig.Status == PromptStatus.OK) //确定, 则将圆添加到数据库
               // if (resJigpl.Status == PromptStatus.OK)
               {
                   Z.db.AddEntityToModeSpace(circle.GetEntity());//画圆
                   break;
               }
               return;
           }
           for (; ; )//画完圆继续jig线,不需要可注释
           {
               PromptResult resJigpl = Z.ed.Drag(poly);//拖动线
               
               if (resJigpl.Status == PromptStatus.Cancel)// 放弃, 则退出.
               {
                   return;
               }
             
               if (resJigpl.Status == PromptStatus.OK)  //确定, 则将线添加到数据库
               {
                   Z.db.AddEntityToModeSpace(poly.Updata());//画多段线
                   break;
               }
               return;
           }
       }
       // private Point3d jCenter; // 圆心
       private double jRadius;  // 半径
       public CircleJig(Point3d center)
           : base(new Circle())  // 继承父类Circle的属性
       {
           ((Circle)Entity).Center = center;  // Entity 转化为Cirecle 对象 复制center
       }
       // 用于更新图像对象 这里更新属性时无需使用事务处理
       protected override bool Update()
       {
           if (jRadius > 0)
           {
               ((Circle)Entity).Radius = jRadius;
           }

           return true;
       }
       // 这个函数的作用是当鼠标在屏幕上移动时 就会被调用 实现这个函数时 一般是用它改变图形的属性 我们在这个类定义的属性
       protected override SamplerStatus Sampler(JigPrompts prompts)
       {
           // 声明拖拽类jig提示信息
           JigPromptPointOptions jppo = new JigPromptPointOptions("\n 请指定圆上的一个点");
           char space = (char)32;
           jppo.Keywords.Add("U");
           jppo.Keywords.Add(space.ToString());
           jppo.UserInputControls = UserInputControls.Accept3dCoordinates;
           jppo.Cursor = CursorType.RubberBand;
           jppo.BasePoint = ((Circle)Entity).Center;
           jppo.UseBasePoint = true;

           // 获取拖拽时鼠标的位置状态
           PromptPointResult ppr = prompts.AcquirePoint(jppo);

           jRadius = ppr.Value.GetDistanceBetweenTwoPoint(((Circle)Entity).Center);
           return SamplerStatus.NoChange; // 继续移动 循环检测
       }


       public Entity GetEntity()
       {
           return Entity;
       }
   }
   public class Polyjig : Autodesk.AutoCAD.EditorInput.DrawJig
   {
       public Point3d location;
       public Point3d basePoint;
       public Polyline polyine = new Polyline();
       public Plane plane = new Plane();
       public int index;
       public static void DrawPLJig()
       {
           PromptPointResult ppr = Z.ed.GetPoint("a");
           if (ppr.Value == null) return;
           Point3d pt = ppr.Value;
           Polyjig poly = new Polyjig(pt);
           for (; ; )
           {
               PromptResult resJigpl = Z.ed.Drag(poly);//拖动线       
               if (resJigpl.Status == PromptStatus.Cancel) // 放弃, 则退出.
               {
                   return;
               }
              
               if (resJigpl.Status == PromptStatus.OK) //确定, 则将线添加到数据库
               {
                   Z.db.AddEntityToModeSpace(poly.Updata());//画多段线
                   break;
               }
               return;
           }
       }
       public Polyjig(Point3d basept)
       {
           location = basept;
           basePoint = basept;
           polyine.AddVertexAt(0, basePoint.Convert2d(plane), 0, 0, 0);
           polyine.AddVertexAt(1, location.Convert2d(plane), 0, 0, 0);
       }

       protected override SamplerStatus Sampler(JigPrompts prompts)
       {
           var opts = new JigPromptPointOptions("\n 输入下一个点");
           opts.UserInputControls = (UserInputControls.Accept3dCoordinates |
               UserInputControls.NoZeroResponseAccepted
               | UserInputControls.NoNegativeResponseAccepted);

           var res = prompts.AcquirePoint(opts);
           if (res.Value != location)
           {
               location = res.Value;
           }
           else
           {
               return SamplerStatus.NoChange;
           }
           if (res.Status == PromptStatus.Cancel)
           {
               return SamplerStatus.Cancel;
           }
           else
           {
               return SamplerStatus.OK;
           }
       }

       protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
       {
           Updata();
           draw.Geometry.Draw(polyine);
           return true;
       }
       public Polyline Updata()
       {
           index = polyine.NumberOfVertices - 1;
           polyine.SetPointAt(index, location.Convert2d(plane));
           basePoint = location;
           return polyine;
       }
   }

其他形式:

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;

namespace UseEntityJig
{
    class CircleJig : EntityJig
    {
        private Point3d m_CenterPt;
        public double m_Radius = 100.0;

        // 派生类的构造函数.
        public CircleJig(Vector3d normal)
            : base(new Circle())
        {
            ((Circle)Entity).Center = m_CenterPt;
            ((Circle)Entity).Normal = normal;
            ((Circle)Entity).Radius = m_Radius;
        }

        protected override bool Update()
        {
            ((Circle)Entity).Center = m_CenterPt;
            ((Circle)Entity).Radius = m_Radius;
            return true;
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            // 定义一个点拖动交互类.
            JigPromptPointOptions optJig = new JigPromptPointOptions
                ("\n请指定圆的圆心或用右键修改半径");
         
            optJig.Keywords.Add("100");
            optJig.Keywords.Add("200");
            optJig.Keywords.Add("300");
            optJig.UserInputControls = UserInputControls.Accept3dCoordinates;

            // 用AcquirePoint函数得到用户输入的点.
            PromptPointResult resJigDis = prompts.AcquirePoint(optJig);
            Point3d curPt = resJigDis.Value;

            if (resJigDis.Status == PromptStatus.Cancel)
            {
                return SamplerStatus.Cancel;
            }

            if (resJigDis.Status == PromptStatus.Keyword)
            {
                switch (resJigDis.StringResult)
                {
                    case "100":
                        m_Radius = 100;
                        return SamplerStatus.NoChange;
                    case "200":
                        m_Radius = 200;
                        return SamplerStatus.NoChange;
                    case "300":
                        m_Radius = 300;
                        return SamplerStatus.NoChange;
                }
            }

            if (m_CenterPt != curPt)
            {
                // 保存当前点.
                m_CenterPt = curPt;
                return SamplerStatus.OK;
            }
            else
            {
                return SamplerStatus.NoChange;
            }
        }

        // GetEntity函数用于得到派生类的实体.
        public Entity GetEntity()
        {
            return Entity;
        }
    }
}

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

namespace UseEntityJig
{
    class EllipseJig : EntityJig
    {
        // 声明全局变量.
        private Point3d m_CenterPt, m_MajorPt;
        private Vector3d m_Normal, m_MajorAxis;
        private int m_PromptCounter;
        private double m_OtherAxisLength, m_RadiusRatio;
        private double m_StartAng, m_EndAng, m_ang1, m_ang2;

        // 派生类的构造函数.
        public EllipseJig(Point3d center, Vector3d vec)
            : base(new Ellipse())
        {
            m_CenterPt = center;
            m_Normal = vec;
        }

        protected override bool Update()
        {
            if (m_PromptCounter == 0)
            {
                // 第一次拖拽时,椭圆的半径比为1,屏幕上显示的是一个圆.
                m_RadiusRatio = 1;
                m_MajorAxis = m_MajorPt - m_CenterPt;
                m_StartAng = 0;
                m_EndAng = 2 * Math.PI;
            }
            else if (m_PromptCounter == 1)
            {
                // 第二次拖拽时,修改了椭圆的半径比,屏幕上显示的是一个完整椭圆.
                m_RadiusRatio = m_OtherAxisLength / m_MajorAxis.Length;
            }
            else if (m_PromptCounter == 2)
            {
                // 第三次拖拽时,修改了椭圆的起初角度,屏幕上显示的是一个终止角度为360度的椭圆弧.
                m_StartAng = m_ang1;
            }
            else if (m_PromptCounter == 3)
            {
                // 第四次拖拽时,修改了椭圆的终止角度,屏幕上显示的是一个最终的椭圆弧.
                m_EndAng = m_ang2;
            }

            try
            {
                if (m_RadiusRatio < 1)
                    // 更新椭圆的参数.
                    ((Ellipse)(Entity)).Set(m_CenterPt, m_Normal, m_MajorAxis, m_RadiusRatio, m_StartAng, m_EndAng);
                else
                {
                    // 如另一条半轴长度超过椭圆弧长轴方向矢量的长度,则要重新定义椭圆弧长轴方向矢量的方向和长度.
                    Vector3d mMajorAxis2 = m_MajorAxis.RotateBy(0.5 * Math.PI, Vector3d.ZAxis).DivideBy(1 / m_RadiusRatio);
                    // 更新椭圆的参数.
                    ((Ellipse)(Entity)).Set(m_CenterPt, m_Normal, mMajorAxis2, 1 / m_RadiusRatio, m_StartAng, m_EndAng);
                }
            }
            catch
            {
                // 此处不需要处理.
            }
            return true;
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            if (m_PromptCounter == 0)
            {
                // 定义一个点拖动交互类.
                JigPromptPointOptions optJigPoint = new JigPromptPointOptions("\n请指定椭圆弧轴上一点");
                // 设置拖拽的光标类型.
                optJigPoint.Cursor = CursorType.RubberBand;
                // 设置拖动光标基点.
                optJigPoint.BasePoint = m_CenterPt;
                optJigPoint.UseBasePoint = true;
                // 用AcquirePoint函数得到用户输入的点.
                PromptPointResult resJigPoint = prompts.AcquirePoint(optJigPoint);
                Point3d curPt = resJigPoint.Value;

                if (curPt != m_MajorPt)
                {
                    // 保存当前点.
                    m_MajorPt = curPt;
                }
                else
                {
                    return SamplerStatus.NoChange;
                }

                if (resJigPoint.Status == PromptStatus.Cancel)
                {
                    return SamplerStatus.Cancel;
                }
                else
                {
                    return SamplerStatus.OK;
                }
            }
            else if (m_PromptCounter == 1)
            {
                // 定义一个距离拖动交互类.
                JigPromptDistanceOptions optJigDis = new JigPromptDistanceOptions
                    ("\n请指定另一条半轴的长度");
                // 设置对拖拽的约束:禁止输入零和负值.
                optJigDis.UserInputControls = UserInputControls.NoZeroResponseAccepted |
                    UserInputControls.NoNegativeResponseAccepted;
                // 设置拖拽的光标类型.
                optJigDis.Cursor = CursorType.RubberBand;
                // 设置拖动光标基点.
                optJigDis.BasePoint = m_CenterPt;
                optJigDis.UseBasePoint = true;

                // 用AcquireDistance函数得到用户输入的距离值.
                PromptDoubleResult resJigDis = prompts.AcquireDistance(optJigDis);
                double radiusRatioTemp = resJigDis.Value;

                if (radiusRatioTemp != m_OtherAxisLength)
                {
                    // 保存当前距离值.
                    m_OtherAxisLength = radiusRatioTemp;
                }
                else
                {
                    return SamplerStatus.NoChange;
                }

                if (resJigDis.Status == PromptStatus.Cancel)
                {
                    return SamplerStatus.Cancel;
                }
                else
                {
                    return SamplerStatus.OK;
                }
            }
            else if (m_PromptCounter == 2)
            {
                // 设置椭圆弧0度基准角.
                double baseAng;
                Vector2d mMajorAxis2d = new Vector2d(m_MajorAxis.X, m_MajorAxis.Y);
                if (m_RadiusRatio < 1)
                {
                    baseAng = mMajorAxis2d.Angle;
                }
                else
                {
                    baseAng = mMajorAxis2d.Angle + 0.5 * Math.PI;
                }

                // 设置系统变量“ANGBASE”.
                Application.SetSystemVariable("ANGBASE", baseAng);
                // 定义一个角度拖动交互类.
                JigPromptAngleOptions optJigAngle1 = new JigPromptAngleOptions("\n请指定椭圆弧的起始角度");
                // 设置拖拽的光标类型.
                optJigAngle1.Cursor = CursorType.RubberBand;
                // 设置拖动光标基点.
                optJigAngle1.BasePoint = m_CenterPt;
                optJigAngle1.UseBasePoint = true;

                // 用AcquireAngle函数得到用户输入的角度值.
                PromptDoubleResult resJigAngle1 = prompts.AcquireAngle(optJigAngle1);
                m_ang1 = resJigAngle1.Value;

                if (m_StartAng != m_ang1)
                {
                    // 保存当前角度值.
                    m_StartAng = m_ang1;
                }
                else
                {
                    return SamplerStatus.NoChange;
                }

                if (resJigAngle1.Status == PromptStatus.Cancel)
                {
                    return SamplerStatus.Cancel;
                }
                else
                {
                    return SamplerStatus.OK;
                }
            }
            else if (m_PromptCounter == 3)
            {
                // 定义一个角度拖动交互类.
                JigPromptAngleOptions optJigAngle2 = new JigPromptAngleOptions("\n请指定椭圆弧的终止角度");
                // 设置拖拽的光标类型.
                optJigAngle2.Cursor = CursorType.RubberBand;
                // 设置拖动光标基点.
                optJigAngle2.BasePoint = m_CenterPt;
                optJigAngle2.UseBasePoint = true;

                // 用AcquireAngle函数得到用户输入的角度值.
                PromptDoubleResult resJigAngle2 = prompts.AcquireAngle(optJigAngle2);
                m_ang2 = resJigAngle2.Value;

                if (m_EndAng != m_ang2)
                {
                    // 保存当前角度值.
                    m_EndAng = m_ang2;
                }
                else
                {
                    return SamplerStatus.NoChange;
                }

                if (resJigAngle2.Status == PromptStatus.Cancel)
                {
                    return SamplerStatus.Cancel;
                }
                else
                {
                    return SamplerStatus.OK;
                }
            }
            else
            {
                return SamplerStatus.NoChange;
            }
        }

        // GetEntity函数用于得到派生类的实体.
        public Entity GetEntity()
        {
            return Entity;
        }

        // setPromptCounter过程用于控制不同的拖拽.
        public void setPromptCounter(int i)
        {
            m_PromptCounter = i;
        }
    }
}

command

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace UseEntityJig
{
    public class Command
    {
        [CommandMethod("jc")]
        public void JigCircleTest()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Matrix3d mt = ed.CurrentUserCoordinateSystem;
            Vector3d normal = mt.CoordinateSystem3d.Zaxis;

            CircleJig circleJig = new CircleJig(normal);

            for (; ; )
            {
                // 拖动
                PromptResult resJig = ed.Drag(circleJig);
                // 放弃, 则退出.
                if (resJig.Status == PromptStatus.Cancel)
                {
                    return;
                }
                // 确定, 则将圆添加到数据库
                if (resJig.Status == PromptStatus.OK)
                {
                    AppendEntity(circleJig.GetEntity());
                    break;
                }
            }
        }

        [CommandMethod("JigEllipse")]
        public void JigEllipseTest()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Database db = Application.DocumentManager.MdiActiveDocument.Database;

            // 备份系统变量“ANGBASE”.
            object oldAngBase = Application.GetSystemVariable("ANGBASE");

            // 普通的点交互操作.
            PromptPointOptions optPoint = new PromptPointOptions("\n请指定椭圆弧的圆心:");
            PromptPointResult resPoint = ed.GetPoint(optPoint);
            if (resPoint.Status != PromptStatus.OK)
            {
                return;
            }

            // 定义一个EntityJig派生类的实例.
            EllipseJig myJig = new EllipseJig(resPoint.Value, Vector3d.ZAxis);

            // 第一次拖拽.
            myJig.setPromptCounter(0);
            PromptResult resJig = ed.Drag(myJig);
            if (resJig.Status != PromptStatus.OK)
            {
                return;
            }

            // 第二次拖拽.
            myJig.setPromptCounter(1);
            resJig = ed.Drag(myJig);
            if (resJig.Status != PromptStatus.OK)
            {
                return;
            }

            // 第三次拖拽.
            myJig.setPromptCounter(2);
            resJig = ed.Drag(myJig);
            if (resJig.Status != PromptStatus.OK)
            {
                return;
            }

            // 第四次拖拽.
            myJig.setPromptCounter(3);
            resJig = ed.Drag(myJig);
            if (resJig.Status != PromptStatus.OK)
            {
                return;
            }

            AppendEntity(myJig.GetEntity());
 
            // 还原系统变量“ANGBASE”.
            Application.SetSystemVariable("ANGBASE", oldAngBase);
        }

        private ObjectId AppendEntity(Entity ent)
        {
            ObjectId entId;
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId,
                    OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject
                    (bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                entId = btr.AppendEntity(ent);
                trans.AddNewlyCreatedDBObject(ent, true);
                trans.Commit();
            }
            return entId;
        }
    }
}


http://www.kler.cn/a/389750.html

相关文章:

  • 软件测试面试题(800道)【附带答案】持续更新...
  • 深入理解 Vue v-model 原理与应用
  • 应对JSON解析键值对乱序问题的实用解决方案
  • 利用 Screen 保持 VSCode 连接远程任务持续运行
  • 常见error集合
  • HTML(超文本标记语言)
  • 【清华大学对应镜像】QGIS+Conda+jupyter玩转Python GIS
  • VMnet NAT模式配置
  • NFS-Ganesha 核心架构解读
  • PostgreSQL中如果有Left Join的时候索引怎么加
  • 【Linux】网络编程2
  • 架构师备考-概念背诵(系统架构)
  • LeetCode 热题100之 动态规划1
  • 如何在短时间内备考集成项目管理工程师
  • 一文学习Android中的Treeview
  • FreeRTOS 23:事件组EventGroup创建、删除、置位操作
  • 逆向攻防世界CTF系列27-200simple-check-100
  • 【HarmonyNext】显示提示文字的方法
  • 【大数据学习 | HBASE高级】storeFile文件的合并
  • 【智谱开放平台-注册/登录安全分析报告】
  • 数据中心类DataCenter(二)
  • 【Linux 31】网络层协议 - IP
  • 【嵌入式设备】蓝牙鼠标使用教程——遥控器编码值
  • Netty篇(WebSocket)
  • VSCode + linux 远程免密登录
  • WSL 2 中 FastReport 与 FastCube 的设置方法与优化策略