Snapping

3DS Max Plug-In SDK

Snapping

See Also: Class Osnap, Class IOSnapManager, Class HitMesh, Class OsnapHit, Class OsnapMarker, Structure SnapInfo, Class Interface, Class ViewExp.

Overview

This topic presents information on object snapping in MAX. 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 MAX.

The 3ds max scene has a single object called the Osnap Manager. At 3ds max startup it will load any object snap plug-ins (those with a DLS extension). Object snap plug-ins 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 plug-ins 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 plug-ins 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 plug-ins.

Class Osnap

This is the base class for creating osnap plug-ins. Conceptually, the osnap class represents a "rule" for locating points in an object’s local space. Typically, an instance of this class will only make sense for certain object types. It’s the job of the ValidInput() method to filter out uninteresting nodes in the scene. When the scene is traversed, each object which passes the input test will be passed into the Snap() method. This method is the workhorse of object snap plug-ins and is responsible for computing, allocating and recording its hits.

Class IOsnapManager

This class provides an interface to the Osnap Manager. Developers who implement osnaps need to record hits with the osnap manager.

Class OsnapHit

This class encapsulates the data required to record a snapped point. Typically a plug-in creates instances of this class and records them with the Osnap Manager. If a snap plug-in needs to record additional data for its hits, it should derive from this class and provide a clone method which copies this additional data and calls the base classes clone method.

Class OsnapMarker

This class is used for drawing osnap markers in the viewports. The marker is drawn as a polyline. The Osnap class must implement the GetMarkers() method which typically returns pointers to these static instances.

Class HitMesh

This is a class to hold a list of object space points for highlighting the geometry associated with a hit. In practice, developers need only implement two methods of this class.

Class Interface

There are several methods in this class related to object snap. The most important one returns a pointer to the Osnap Manager. See Interface Osnap Methods.

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.

int CylinderObjCreateCallBack::proc(ViewExp *vpt,int msg, int point,

int flags, IPoint2 m, Matrix3& mat ) {

float r;

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

Some simple sample code provided in the SDK for demonstrating object snap is the sphere object snap plug-in. It provides two additional snaps to MAX. These are the center of the sphere and the quadrant points on the sphere. This code is available in \MAXSDK\SAMPLES\SNAPS\SPHERE\SPHERE.CPP.

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.