Picking Points in the Viewports

pickPoint [ prompt:<string> ] [ snap:#2D|#3D ]      \

           [ rubberBand:<start_point3> ]            \

           [ mouseMoveCallback:fn | #(fn,arg) ]     \

           [ terminators:#(<string>,<string>,...) ]

The pickPoint() function lets the user pick a 3D point in a 3ds max viewport or type in a 3D point in the Listener. When called, the function puts 3ds max into a special point-picking command mode and the cursor changes to a cross-hair. The user can either click in one of 3ds max's viewports or type a 3D point into the Listener and the function returns that point as a MAXScript Point3 value in world-space coordinates.

The function takes an optional prompt: string argument which it prints in the Listener as a prompt message. There is also an optional snap: keyword argument that controls viewport point picking if Snap is turned on in the 3ds max interface. If #3D is specified, the cursor snaps to points anywhere in 3D space, if #2D is specified (the default), the cursor only snaps on the current active grid construction plane. If Snap is off in the 3ds max interface, the clicked point is always taken to be on the current active grid construction plane.

The user can either press the ESC key or click the right mouse button at any time to abort the point picking and the function immediately returns the special MAXScript value #escape if the escape key is pressed or #rightClick if the right mouse button is clicked.

You can get the pickPoint() function to display a rubberbanding dashed line during point input by supplying the optional keyword argument rubberBand:<start_point3>. If you include this on a call to pickPoint(), it rubberbands a dashed line from the specified start point to follow the mouse. You would use it in a chain of point picks by specifying the last picked point as the rubberBand: start point for each successive pick. The start point given to rubberBand: should be in world coordinates.

You can also set up a mouse move callback function for tracking free mouse moves during point input. The optional keyword argument for this is mouseMoveCallback: and it has two forms:

mouseMoveCallback:fn

mouseMoveCallback:#(fn, arg)

The second form allows you to supply an argument value that is sent to the callback function each time it is called.

The fn you supply should take one argument in the first form above and two in the second. When the callback function is called, the first argument it gets is always the current world coordinates of the mouse and the second if given is the arg you supplied. You can use a callback function to implement a more sophisticated form of rubberbanding, for example by adjusting a spline's vertex or a box's height to follow the mouse. If you do this, make sure you call any needed update() mesh or spline functions.

The pickPoint() function allows coordinates to be entered either by clicking in a 3ds max viewport or by typing numbers into the MAXScript Listener window. The user can enter coordinates in one of several forms (based on the command line input syntax for AutoCAD), as follows:

x, y, z

explicit point in current construction plane coordinates

x, y

point on the construction plane (cp)

d

point d units away in mouse direction from last point

@ x, y, z

relative, offset to last input point

@ x, y

on cp, relative to last point's projection on cp

d < a

polar on cp, distance from cp origin at a angle from x-axis

@ d < a

relative polar on cp, centered on last point

d < a1 < a2

spherical on cp, d from cp origin at a1 from x and a2 angle from xy-plane

@ d < a1 < a2

relative spherical

There can be zero or more white space characters before and between numbers and metacharacters.

Note that these typed-coordinates are always interpreted as relative to the current active grid construction plane and that coordinates returned by pickPoint() are always in world-space.

Keyboard input by the user that is not in one of the expected coordinate input forms is returned as a String value so the author can handle the error gracefully or permit other kinds of input to be parsed by the script.

You can test for these return conditions using the classOf() function, for example:

p = pickPoint()

case of

(

(p == undefined): ... -- user pressed escape

(p == #rightClick): ... -- user clicked RMB

(classOf p == Point3): ... -- user entered a point

(classOf p == String): ... -- user keyed a non-point

)

The terminators: keyword argument expects an array of 1 or more strings each of 1 or more characters. When supplied, this list of strings specifies a set of keyboard input terminating character sequences. If any one of them is typed at the end of some input, the pickPoint() function returns immediately without waiting for an ENTER to be typed. In all cases when the terminators: keyword argument is supplied, the pickPoint() function returns a two-element array--the first element is the input point, the second element is the terminating string, or undefined if the point was input with a mouse click or terminated with ENTER.

This allows the user to type in a point terminated by a terminator string, or just type the terminator string. In the second case, the first element in the result array is the value undefined. You can inspect the second element in the array to see what terminator, if any, the user actually typed. For example,

      pp = pickPoint prompt:"foo: " terminators:#(" ", "a", "oo")

      if pp[2] == "a" then ...

Often, the pickPoint() function will be used repeatedly within a script to request multiple points, such as successive vertices in a line. You may need to use the new function, redrawViews(), to force a viewport update as you gradually construct new scene objects this way. MAXScript normally delays viewport redraw until the script finishes running.

pickOffsetDistance [ prompt:<string> ] [ pt2Prompt:<string> ] \

                   [ errPrompt:<string> ] [ snap:#2D|#3D ]    \

                   [ keyword:<string> ]

This function issues the prompt message, if any, to Listener and waits for the user to either click in a viewport (which determines a point exactly like the pickPoint() function), to type in a number ended by ENTER (which determines a number), or to type all or the beginning of the keyword ended by ENTER. If the user types the keyword, the function returns true. If the user types a number, the function returns its value. If the user clicks a point, the function issues the pt2Prompt message, if any, to Listener and waits for a second point to be clicked, and then returns the world-space distance between the two points. If the user types something which is not a number and does not match the keyword, the function issues the errPrompt message, if any, otherwise the prompt message, if any, and waits for the user to try again.