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

可实现效果如下:

cs 复制代码
   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;
       }
   }

其他形式:

cs 复制代码
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;
        }
    }
}
cs 复制代码
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

cs 复制代码
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;
        }
    }
}
相关推荐
学前端的小朱1 分钟前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
HEU_firejef30 分钟前
Redis——缓存预热+缓存雪崩+缓存击穿+缓存穿透
数据库·redis·缓存
摇光931 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务
沐泽Mu1 小时前
嵌入式学习-QT-Day09
开发语言·qt·学习
小猿_001 小时前
C语言实现顺序表详解
c语言·开发语言
KELLENSHAW1 小时前
MySQL45讲 第三十七讲 什么时候会使用内部临时表?——阅读总结
数据库·mysql
余~~185381628001 小时前
NFC 碰一碰发视频源码搭建技术详解,支持OEM
开发语言·人工智能·python·音视频
GOATLong2 小时前
c++智能指针
开发语言·c++
Dola_Pan2 小时前
C语言:随机读写文件、实现文件复制功能
c语言·开发语言