Snapping

Objects snaps are a plug-in type that allow objects to provide the 3ds Max snapping system with additional points that may be snapped to. For example, the built in snap system provides the ability to snap to points such as vertices, endpoints, midpoints, etc. A developer of a procedural sphere object might want to provide additional snaps for center point and quadrant points. By deriving a class from Osnap and implement its methods a developer can seamlessly provide this functionality in 3ds Max.

The 3ds Max scene has a single object called the Osnap Manager. At 3ds Max startup it will load any object snap plugins (those with a DLS extension). Object snap plugins are derived from class Osnap. This class has various methods that allow the system to query it about potential objects to be snapped to. That is, when 3ds Max is traversing the scene doing a hit test the Osnap Manger will call each of the plugins to snap against a particular node. The Osnap class has a method that allows it to tell the Osnap Manager if it wants to snap to the specified object type based on its Super Class ID and Class ID. For example, NURBS snaps only respond to NURBS objects. Tangent and Perpendicular snaps only respond to Spline objects. If the object snap plugins do want to snap to the object type, they can register a set of points to snap to. For instance, the sphere above would register the center and quadrant points.

This system allows developers to implement very specific snapping behaviors. For example, a door object might have a special snap mode that always snaps to the hinge point.

Principal Classes

The following are the main classes associated with creating object snap plugins.

Handling Snap Preview and Point Snap in Creation Procedures

The ViewExp::SnapPoint() method has been enhanced in 3ds Max 2.0 to work with the new object snap system. A change that developers will need to make is that any mouse procs which will be calling ViewExp::SnapPoint() will need to add a call to ViewExp::SnapPreview() as in the following code fragment from \MAXSDK\SAMPLES\OBJECTS\CYL.CPP.

intCylinderObjCreateCallBack::proc(
          ViewExp *vpt,
          int msg,
          int point,
          int flags,
          IPoint2m,
          Matrix3& mat )
{
   floatr;
   if (msg == MOUSE_FREEMOVE)
   {
     vpt->SnapPreview(m,m,NULL, SNAP_IN_3D);
   }
   if (msg==MOUSE_POINT||msg==MOUSE_MOVE)
   {
     switch(point)
     {
      case 0:
      ob->suspendSnap = TRUE;
      sp0 = m;
      p[0 = vpt->SnapPoint(m,m,NULL,SNAP_IN_3D);
      //...
     }
     //...
   }
   //...
}
 

Sample Code

The main code where snapping is handled for Geometric Objects, Shape Objects, Cameras, Lights and Helpers is available in \MAXSDK\SAMLES\SNAPS\XMESH\XMESH.CPP.