I was up in Adelboden, this weekend, for the Men's FIS World Cup Slalom and Giant Slalom events. Yes, just watching – not participating 🙂 – although I did get the chance to catch a few much gentler slopes on my snowboard during the course of the weekend.

FIS World Cup in Adelboden

On the Saturday – during the Giant Slalom – there was a pretty amazing incident: a young Norwegian competitor, Henrik Kristofferson, very nearly hit a television worker during his first run down. Thankfully no-one was hurt, and Henrik was very understanding about the whole thing (he was given a restart but, given the fact he was at the end of a grueling descent when the collision so nearly happened, there was very little chance of him contending, at that point). Henrik did go on to come third in the following day's Slalom event which is something, at least.

While I was on the slopes, I had the chance to think about a comment submitted on Friday by Mark Douglas in response to this previous post:

Is it possible thru code like this to prevent a user from creating anything that is not inserted, drawn or connected to an osnap? I.E. A way to make sure a user is always drawing things that are connected to other objects via OSNAP? Use case is where someone is not drawing accurately this would only allow them to place items via OSNAP settings and not miss endpoints and such. (Obviously some times you have to, but it would be like training wheels for people drafting) Just a thought..

At first I thought this was going to be complicated to implement, but then I remembered the PointFilter mechanism. This is a bit like the very handy PointMonitor event handler but it also allows you to manipulate the "input" points that get computed inside AutoCAD and even to reject ones you don't like. As with the PointMonitor, you also get some "history" information about the way the point was computed, which happily includes whether an object snap was used or not.

All in all the code ended up being very simple. Here's some C# code implementing a command (FORSNAP) which enables a mode that forces users only to snap to objects. There's a matching UNFORSNAP command, of course, as this is just the kind of mode that could drive people crazy if enabled and left on. (Any of you with a practical joker in your department who knows how to use Visual Studio should bear this in mind in case strange things start to happen… 😉

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

 

namespace OnlyObjectSnapping

{

  public class Commands

  {

    [CommandMethod("FORSNAP")]

    public static void ForceObjectSnapping()

    {

      var doc = Application.DocumentManager.MdiActiveDocument;

      var ed = doc.Editor;     

      ed.PointFilter += new PointFilterEventHandler(OnPointFilter);

    }

 

    [CommandMethod("UNFORSNAP")]

    public static void DisableForcedObjectSnapping()

    {

      var doc = Application.DocumentManager.MdiActiveDocument;

      var ed = doc.Editor;

&
#160;     ed.PointFilter -=
new PointFilterEventHandler(OnPointFilter);

    }

 

    static void OnPointFilter(object sender, PointFilterEventArgs e)

    {

      // Only if a command is active

 

      bool cmdActive =

        (short)Application.GetSystemVariable("CMDACTIVE") == 1;

      if (e.Context.PointComputed && cmdActive)

      {

        // Check whether the point has been computed via an

        // object snap

 

        if (

          (e.Context.History & PointHistoryBits.ObjectSnapped) == 0

        )

        {

          // If not, don't accept it

 

          e.Result.Retry = true;

        }

      }

    }

  }

}

Tomorrow I'll be waking up at the crack of dawn to head to Tel Aviv. Hopefully I'll get the chance to report back on my visit to the Autodesk office there at some point during the coming week.

3 responses to “Forcing AutoCAD object snapping using .NET”

  1. Kean,

    I am interested in utilizing the PointFilter event to capture and record the points used inside a given command. I am having an issue discerning the current location of the cursor vs. a specified point as the event is firing whenever the cursor is moved, not just when a point is chosen. I am finding it strange that even the PromptedForPoint event is firing continuously as you move the cursor around the screen. Are these the intended behaviors?

    1. Matt,

      Yes, that's intended.

      Do you want the user to select a point? If so, then you should just use Editor.GetPoint(). If you want to hook into the selection that's happening in existing commands, then the notifications will come like this (repeatedly).

      By the way, you probably want to use a PointMonitor rather than a PointFilter unless you actually want to filter stuff out.

      Regards,

      Kean

      1. Kean,

        Thank you for your quick response. I do want the user to select a point. In fact I am attempting to create reactors to hook into the COPY command, to handle some cleanup of custom objects when they are copied using that method. I have decided to, while I continue to understand, create my own COPY like command that handles the aforementioned cleanup. I am interested in grabbing the Base points and subsequent points, firing an event when objects are opened for modify to further manipulate them using displacement between the base point and last specified point.

        Regards,

        Matt

  2. Hello Kean

    You post is already 11 years old!

    But i came across it few days ago after searching for how to control Osnap on specific chosen objects.

    I am far from being a developer or having any knoledge on this field.

    But after reading you post, I feel that even I could go ahead and use your solution.

    So i ask: is there any tutorial on how to use your code in Visual Basci do generate the .DLL file that will do the trick?

    Thank you very much!

    1. Hi João,

      You might be able to go back to the very first few posts on this blog, which should give you some clues. Otherwise you might ask for help on the AutoCAD .NET forum.

      Best regards,

      Kean

      1. Thank you very much!

Leave a Reply to João Cancel reply

Your email address will not be published. Required fields are marked *