admin 管理员组文章数量: 1086759
AutoCAD二次开发夹点规则重定义
今天我们学习的这个例子是关于规则重定义中的夹点重定义,关于规则重定义我们之前有提到过的。在这里我们就不在细致说明了。今天我们来学习这个夹点重定义,这个例子是选择了一个圆,然后再为这个圆创建两条过圆心的直线(也就是直径),然后我们现在要做的是移动直线与圆的交点,或者圆心,图形也随着变化。那么在这个例子我们会用到扩展数据,存储直线经过圆心的角度,以便每次重绘制。可以细细品味代码。
来看一下录制的效果。
下面看一下代码。
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;namespace DevDaysGripMenusSample
{public class TestOverrule{private static DrawOverrule m_drawOverrule = new DrawOverrule();private static PropsOverrule m_propertiesOverrule = new PropsOverrule();private static XformOverrule m_xformOverrule = new XformOverrule();private static ObjectSnapOverrule m_osnapOverrule = new ObjectSnapOverrule();private static GripPointOverrule m_gripOverrule = new GripPointOverrule();private static HiliteOverrule m_hightlightOverrule = new HiliteOverrule();private static ObjOverrule m_objectOverrule = new ObjOverrule();private static Overrule[] m_overrules = new Overrule[]{m_drawOverrule,m_propertiesOverrule,m_xformOverrule,m_osnapOverrule,m_gripOverrule,m_hightlightOverrule,m_objectOverrule};private static System.Collections.Generic.List<ObjectId> m_overruledObjects = new System.Collections.Generic.List<ObjectId>();private static readonly string RegAppName = "AsdkOverruleTest";private static bool m_overruleAdded = false;[CommandMethod("overrule")]static public void Start(){Document doc = Application.DocumentManager.MdiActiveDocument;Editor ed = doc.Editor;PromptEntityResult res = ed.GetEntity("Select a circle to overrule");if (res.Status != PromptStatus.OK)return;if (res.ObjectId.ObjectClass != RXObject.GetClass(typeof(Circle))){ed.WriteMessage("Selected object is not a circle!\n");return;}if (m_overruledObjects.Count == 0){Application.DocumentManager.DocumentToBeDestroyed += new DocumentCollectionEventHandler(DocumentManager_DocumentToBeDestroyed);}if (!m_overruledObjects.Contains(res.ObjectId)){Database db = res.ObjectId.Database;using (Transaction t = db.TransactionManager.StartTransaction()){RegAppTable tbl = (RegAppTable)t.GetObject(db.RegAppTableId, OpenMode.ForRead, false);if (!tbl.Has(RegAppName)){RegAppTableRecord app = new RegAppTableRecord();app.Name = RegAppName;tbl = (RegAppTable)t.GetObject(db.RegAppTableId, OpenMode.ForWrite, false);tbl.Add(app);t.AddNewlyCreatedDBObject(app, true);}Circle c = (Circle)t.GetObject(res.ObjectId, OpenMode.ForRead);if (c.GetXDataForApplication(RegAppName) == null){c = (Circle)t.GetObject(res.ObjectId, OpenMode.ForWrite);c.XData = new ResultBuffer(new TypedValue((int)DxfCode.ExtendedDataRegAppName, RegAppName),new TypedValue((int)DxfCode.ExtendedDataReal, Math.PI / 6) //start with 30 degrees);m_overruledObjects.Add(res.ObjectId);}t.Commit();}}ObjectId[] ids = m_overruledObjects.ToArray();foreach (Overrule o in m_overrules){o.SetIdFilter(ids);if (!m_overruleAdded)Overrule.AddOverrule(RXObject.GetClass(typeof(Circle)), o, false);}m_overruleAdded = true;Application.DocumentManager.MdiActiveDocument.Editor.Regen();}private static void End(){foreach (Overrule o in m_overrules){Overrule.RemoveOverrule(RXObject.GetClass(typeof(Circle)), o);}Overrule.Overruling = false;Application.DocumentManager.MdiActiveDocument.Editor.Regen();}private static void DocumentManager_DocumentToBeDestroyed(object sender, DocumentCollectionEventArgs e){//remove the ids that are going awayfor (int i = m_overruledObjects.Count - 1; i >= 0; i--)if (m_overruledObjects[i].Database == e.Document.Database)m_overruledObjects.RemoveAt(i);ObjectId[] ids = m_overruledObjects.ToArray();foreach (Overrule o in m_overrules)o.SetIdFilter(ids);}private static double GetAngle(Circle c){ResultBuffer rb = c.GetXDataForApplication(RegAppName);return (double)rb.AsArray()[1].Value;}private static LineSegment3d[] GetLines(Circle c){LineSegment3d[] lines = new LineSegment3d[2];double angle = GetAngle(c);Point3d center = c.Center;Vector3d normal = c.Normal;Vector3d axis = normal.GetPerpendicularVector() * c.Radius;Vector3d vec = axis.RotateBy(angle, normal);lines[0] = new LineSegment3d(center - vec, center + vec);vec = axis.RotateBy(-angle, normal);lines[1] = new LineSegment3d(center - vec, center + vec);return lines;}private class DrawOverrule : DrawableOverrule{public override bool WorldDraw(Drawable drawable, WorldDraw wd){Circle c = (Circle)drawable;LineSegment3d[] lines = GetLines(c);foreach (LineSegment3d l in lines)wd.Geometry.WorldLine(l.StartPoint, l.EndPoint);return base.WorldDraw(drawable, wd);}}private class PropsOverrule : PropertiesOverrule{public override void List(Entity entity){Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;ed.WriteMessage("\tOverrule test\n");ed.WriteMessage("\t\tAngle is {0}", GetAngle((Circle)entity));}}private class XformOverrule : TransformOverrule{public override void Explode(Entity entity, DBObjectCollection entitySet){Circle c = (Circle)entity;entitySet.Add((Circle)entity.Clone());LineSegment3d[] lines = GetLines(c);foreach (LineSegment3d l in lines)entitySet.Add(new Line(l.StartPoint, l.EndPoint));}}private class CircleMFMGPE : MultiModesGripPE{internal CircleMFMGPE(GripPointOverrule overrule): base(){m_overrule = overrule;}public override GripMode CurrentMode(Entity entity, GripData gripData){if (gripData is GripPointOverrule.MyGrip){int index = (int)((GripPointOverrule.MyGrip)gripData).CurrentModeId - (int)GripMode.ModeIdentifier.CustomStart;return ((GripPointOverrule.MyGrip)gripData).Modes[index];}elsereturn null;}public override uint CurrentModeId(Entity entity, GripData gripData){if (gripData is GripPointOverrule.MyGrip)return (uint)(gripData as GripPointOverrule.MyGrip).CurrentModeId;return 0;}public override bool GetGripModes(Entity entity, GripData gripData, GripModeCollection modes, ref uint curMode){if (!(gripData is GripPointOverrule.MyGrip))return false;return (gripData as GripPointOverrule.MyGrip).GetGripModes(ref modes, ref curMode);}public override MultiModesGripPE.GripType GetGripType(Entity entity, GripData gripData){return (gripData is GripPointOverrule.MyGrip) ? MultiModesGripPE.GripType.Secondary : MultiModesGripPE.GripType.Primary;}public override void Reset(Entity entity){}public override bool SetCurrentMode(Entity entity, GripData gripData, uint curMode){if (!(gripData is GripPointOverrule.MyGrip))return false;(gripData as GripPointOverrule.MyGrip).CurrentModeId = (GripMode.ModeIdentifier)curMode;return true;}private GripPointOverrule m_overrule;}private class GripPointOverrule : GripOverrule{private CircleMFMGPE __theMFMGPE = null;internal GripPointOverrule(){__theMFMGPE = new CircleMFMGPE(this);RXObject.GetClass(typeof(Circle)).AddX(RXObject.GetClass(typeof(CircleMFMGPE)), __theMFMGPE);}internal abstract class MyGrip : GripData{protected MyGrip(){__modes = new GripModeCollection();}private GripMode.ModeIdentifier __curModeId = GripMode.ModeIdentifier.CustomStart;public virtual GripMode.ModeIdentifier CurrentModeId{get { return __curModeId; }set { __curModeId = value; }}private GripModeCollection __modes;public virtual GripModeCollection Modes{get { return __modes; }}public abstract void Move(Entity entity, Vector3d offset);public abstract bool GetGripModes(ref GripModeCollection modes, ref uint curMode);public override bool ViewportDraw(ViewportDraw vd, ObjectId entityId, GripData.DrawType type, Point3d? imageGripPoint, int gripSize){Point2d unit = vd.Viewport.GetNumPixelsInUnitSquare(GripPoint);vd.Geometry.Circle(GripPoint, gripSize / unit.X, vd.Viewport.ViewDirection);return true;}protected void MoveWorker(Entity entity, Vector3d offset){Circle c = (Circle)entity;Point3d newGripPoint = GripPoint + offset;c.Radius = newGripPoint.DistanceTo(c.Center);}}public class RowGripMenuItem : Autodesk.AutoCAD.Runtime.IMenuItem{private GripData _Grip;private Action _Action;private List<IMenuItem> _Items = new List<IMenuItem>();public delegate void Action(GripData g, RowGripMenuItem r);public RowGripMenuItem(GripData g, Action a){_Grip = g;_Action = a;}public bool Checked { get; set; }public bool Enabled { get; set; }public System.Drawing.Icon Icon { get; set; }public string Text { get; set; }public bool Visible { get; set; }public System.Collections.Generic.IEnumerable<Autodesk.AutoCAD.Runtime.IMenuItem> Items{get { return _Items; }}public void OnClicked(System.EventArgs eventArgs){if (_Action != null)_Action.Invoke(_Grip, this);}public void Add(IMenuItem m){_Items.Add(m);}public void Remove(IMenuItem m){_Items.Remove(m);}public event EventHandler Click;}private class LowerLeftGrip : MyGrip{public enum myMFMGPEModeId{kStretchRadiusX = GripMode.ModeIdentifier.CustomStart,kStretchRadiusY,kIncrementRadiusByOne}public LowerLeftGrip(){GripMode m1 = new GripMode();m1.ModeId = (uint)myMFMGPEModeId.kStretchRadiusX;m1.DisplayString = "Stretch radius, offset mapped to X diection.";m1.CLIPromptString = "\nSpecify new vertex point:";m1.CLIKeywordList = "STretch MOve ROtate SCale MIrror Base Copy Undo X EXit dummy GMove CGizmo _STretch MOve ROtate SCale MIrror Base Copy Undo X EXit dummy GMove CGizmo";m1.CLIDisplayString = "\n** STRETCH X **";m1.Action = GripMode.ActionType.DragOn;Modes.Add(m1);GripMode m2 = new GripMode();m2.ModeId = (uint)myMFMGPEModeId.kStretchRadiusY;m2.DisplayString = "Stretch radius, offset mapped to Y diection.";m2.CLIDisplayString = "\n** STRETCH Y **";m1.CLIKeywordList = "STretch MOve ROtate SCale MIrror Base Copy Undo X EXit dummy GMove CGizmo _STretch MOve ROtate SCale MIrror Base Copy Undo X EXit dummy GMove CGizmo";m2.CLIPromptString = "\nSpecify new vertex point:";m2.Action = GripMode.ActionType.DragOn;Modes.Add(m2);GripMode m3 = new GripMode();m3.ModeId = (uint)myMFMGPEModeId.kIncrementRadiusByOne;m3.DisplayString = "Increment radius by 1.";m3.CLIPromptString = "\nSpecify new vertex point:";m3.CLIKeywordList = "STretch MOve ROtate SCale MIrror Base Copy Undo X EXit dummy GMove CGizmo _STretch MOve ROtate SCale MIrror Base Copy Undo X EXit dummy GMove CGizmo";m3.CLIDisplayString = "\n** INCREMENT RADIUS BY 1 **";m3.Action = GripMode.ActionType.Immediate;Modes.Add(m3);CurrentModeId = 0;}public override bool GetGripModes(ref GripModeCollection modes, ref uint curMode){//modes = __modes;foreach (GripMode m in Modes)modes.Add(m);//curMode = (uint)CurrentModeId;return true;}public override void Move(Entity entity, Vector3d offset){switch ((myMFMGPEModeId)CurrentModeId){case myMFMGPEModeId.kStretchRadiusX:offset = offset.Subtract(new Vector3d(0, offset.Y, 0));break;case myMFMGPEModeId.kStretchRadiusY:offset = offset.Subtract(new Vector3d(offset.X, 0, 0));break;case myMFMGPEModeId.kIncrementRadiusByOne:Vector3d v = GripPoint - ((Circle)entity).Center;offset += v.GetNormal();break;}MoveWorker(entity, offset);return;}public override IEnumerable<Autodesk.AutoCAD.Runtime.IMenuItem> OnRightClick(GripDataCollection hotGrips, ObjectIdCollection entities){List<RowGripMenuItem> GripMenu = new List<RowGripMenuItem>();GripMenu.Add(new RowGripMenuItem(this, null){Text = "Test-1",Icon = Resource1.MyTestIcon});GripMenu.Add(new RowGripMenuItem(this, null){Text = "Test - 2",Icon = Resource1.MyTestIcon});return GripMenu;}}private class UpperRightGrip : MyGrip{public override bool GetGripModes(ref GripModeCollection modes, ref uint curMode){GripMode m1 = new GripMode();m1.ModeId = 0;m1.DisplayString = "Upper right not implemeted";m1.Action = GripMode.ActionType.Immediate;modes.Add(m1);curMode = 0;return true;}public override void Move(Entity entity, Vector3d offset){MoveWorker(entity, offset);}}private class UpperLeftGrip : MyGrip{public override bool GetGripModes(ref GripModeCollection modes, ref uint curMode){GripMode m1 = new GripMode();m1.ModeId = 0;m1.DisplayString = "Upper left not implemeted";m1.Action = GripMode.ActionType.Immediate;modes.Add(m1);curMode = 0;return true;}public override void Move(Entity entity, Vector3d offset){MoveWorker(entity, offset);}}private class LowerRightGrip : MyGrip{public override bool GetGripModes(ref GripModeCollection modes, ref uint curMode){GripMode m1 = new GripMode();m1.ModeId = 0;m1.DisplayString = "Lower right not implemeted";m1.Action = GripMode.ActionType.Immediate;modes.Add(m1);curMode = 0;return true;}public override void Move(Entity entity, Vector3d offset){MoveWorker(entity, offset);}}private GripData[] m_grips = new GripData[4];public override void GetGripPoints(Entity entity, GripDataCollection grips, double curViewUnitSize, int gripSize, Vector3d curViewDir, Autodesk.AutoCAD.DatabaseServices.GetGripPointsFlags bitFlags){base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags);Circle c = (Circle)entity;LineSegment3d[] lines = GetLines(c);m_grips[0] = new LowerLeftGrip();m_grips[0].GripPoint = lines[0].StartPoint;m_grips[1] = new UpperRightGrip();m_grips[1].GripPoint = lines[0].EndPoint;m_grips[2] = new UpperLeftGrip();m_grips[2].GripPoint = lines[1].StartPoint;m_grips[3] = new LowerRightGrip();m_grips[3].GripPoint = lines[1].EndPoint;foreach (GripData g in m_grips)grips.Add(g);}public override void MoveGripPointsAt(Entity entity, GripDataCollection grips, Vector3d offset, Autodesk.AutoCAD.DatabaseServices.MoveGripPointsFlags bitFlags){foreach (GripData grip in grips){MyGrip myGrip = grip as MyGrip;if (myGrip != null)myGrip.Move(entity, offset);elsebase.MoveGripPointsAt(entity, grips, offset, bitFlags);}}}private class ObjectSnapOverrule : OsnapOverrule{public override void GetObjectSnapPoints(Entity entity, ObjectSnapModes snapMode, IntPtr gsSelectionMark, Point3d pickPoint, Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, IntegerCollection geometryIds){base.GetObjectSnapPoints(entity, snapMode, gsSelectionMark, pickPoint, lastPoint, viewTransform, snapPoints, geometryIds);if ((snapMode & ObjectSnapModes.ModeEnd) == ObjectSnapModes.ModeEnd){Circle c = (Circle)entity;LineSegment3d[] lines = GetLines(c);foreach (LineSegment3d l in lines){snapPoints.Add(l.StartPoint);snapPoints.Add(l.EndPoint);}}}}private class HiliteOverrule : HighlightOverrule{public override void Highlight(Entity entity, FullSubentityPath subId, bool highlightAll){base.Highlight(entity, subId, highlightAll);}public override void Unhighlight(Entity entity, FullSubentityPath subId, bool highlightAll){base.Unhighlight(entity, subId, highlightAll);}}private class ObjOverrule : ObjectOverrule{public override void Erase(DBObject dbObject, bool erasing){//prevent the object from being deletedbase.Erase(dbObject, erasing);if (erasing)throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.CannotBeErasedByCaller);}}}
}
更多内容,敬请关注公众号
本文标签: AutoCAD二次开发夹点规则重定义
版权声明:本文标题:AutoCAD二次开发夹点规则重定义 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1698698457a314598.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论