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;
        }
    }
}
相关推荐
湫ccc18 分钟前
《Python基础》之pip换国内镜像源
开发语言·python·pip
fhvyxyci19 分钟前
【C++之STL】摸清 string 的模拟实现(下)
开发语言·c++·string
qq_4597300321 分钟前
C 语言面向对象
c语言·开发语言
打鱼又晒网24 分钟前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
大白要努力!29 分钟前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
菜鸟学Python30 分钟前
Python 数据分析核心库大全!
开发语言·python·数据挖掘·数据分析
一个小坑货37 分钟前
Cargo Rust 的包管理器
开发语言·后端·rust
bluebonnet2742 分钟前
【Rust练习】22.HashMap
开发语言·后端·rust
古月居GYH42 分钟前
在C++上实现反射用法
java·开发语言·c++
吾与谁归in1 小时前
【C#设计模式(13)——代理模式(Proxy Pattern)】
设计模式·c#·代理模式