With Autodesk.AutoCAD.DatabaseServices.OspanOverrule, this is actually a very easy achievable thing to do.
Here is the code sample of the custom OsnapOverrule:
using System; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; namespace CentroidSnap { public class MyCentroidSnap : OsnapOverrule { private static MyCentroidSnap _instance = null; private bool _overruling = false; private bool _started = false; public static MyCentroidSnap Instance { get { if (_instance == null) _instance = new MyCentroidSnap(); return _instance; } } public bool Started { get { return _started; } } public void StartOSnap() { _overruling = Overruling; Overrule.AddOverrule(RXClass.GetClass(typeof(Curve)), this, true); Overruling = true; _started = true; } public void StopOSnap() { Overrule.RemoveOverrule(RXClass.GetClass(typeof(Curve)), this); Overruling = _overruling; _started = false; } #region overriden methods public override void GetObjectSnapPoints( Entity entity, ObjectSnapModes snapMode, IntPtr gsSelectionMark, Point3d pickPoint, Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, IntegerCollection geometryIds) { bool hasCentre = true; Point3d snapPt = new Point3d(); if (entity is Polyline) { Polyline pl = (Polyline)entity; if (pl.Closed) { snapPt = GetPolylineCentre(pl); } else { hasCentre = false; } } else if (entity is Circle) { snapPt = ((Circle)entity).Center; } else { hasCentre = false; } if (hasCentre) { //Clear all possible existing snap points snapPoints.Clear(); //Set OSnap mode to NEA snapMode = ObjectSnapModes.ModeNear; snapPoints.Add(snapPt); } } public override bool IsContentSnappable(Entity entity) { return false; } #endregion #region private methods private Point3d GetPolylineCentre(Polyline pl) { double x = 0.0, y = 0.0, z = 0.0; for (int i=0; i<pl.NumberOfVertices; i++) { Point3d p = pl.GetPoint3dAt(i); x += p.X; y += p.Y; z += p.Z; } return new Point3d( x / pl.NumberOfVertices, y / pl.NumberOfVertices, z / pl.NumberOfVertices); } #endregion } }
Here is the command class to start/stop the custom MyCentroidSnap overrule:
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using CadApp = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(CentroidSnap.MyCadCommands))] namespace CentroidSnap { public class MyCadCommands { [CommandMethod("CSnap")] public static void RunMyCadCommand() { Document dwg = CadApp.DocumentManager.MdiActiveDocument; Editor ed = dwg.Editor; if (!MyCentroidSnap.Instance.Started) { MyCentroidSnap.Instance.StartOSnap(); ed.WriteMessage( "\nMYCentroidOSnap is started."); } else { MyCentroidSnap.Instance.StopOSnap(); ed.WriteMessage( "\nMYCentroidOSnap is stopped."); } Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt(); } } }
I also posted on the same topic a couple of years ago here, here and here. Obviously, I could have also create this MyCentroidSnap class by deriving it from Autodesk.AutoCAD.GraphicsInterface.Glyph class.
As usual, see this video clip for the MyCentroidSnap's action.
Hi, I would like to ask you some things. Please contact me if ever. Thank You
ReplyDeleteemail: d.richardcarl@gmail.com