Selection and Picking


Introduction

The View3D widget class provides a complete set of public functions, actions and callbacks to handle object selection and picking.

Object Selection

Each object in a View3D display can be selected based on action View3DSelectObject. This action is connected to Button1 in the default translation table. Multiple selections can be obtained by pressing the Control key while selecting additional objects with Button1. An argument (single or multiple) must be specified to differentiate between a single or a multiple selection.

    None<Btn1Down>:    View3DSelectObject(single)
    !Ctrl<Btn1Down>:   View3DSelectObject(multiple)

Callback XmNselectCallback is invoked by action View3DSelectObject each time an object is selected. Selected objects are highlighted based on the content of resource XmNselectMode. The default for this resource is to highlight objects by drawing the outline of the object using the color specified with resource XmNhighlightColor4 and the line thickness specified with resource XmNhighlightThickness.

By default, each object added to a View3D viewer is selectable. Use function XintView3DSetSelectable to control whether or not an object is selectable.


Picking

Action View3DPickObject allows the application to implement picking. This action is not included in the default translation table, but can be added after a View3D widget has been created using function XtOverrideTranslations for example. Action View3DPickObject returns precise information regarding where the pick was done, which vertex was closest, the normal to the object at the intersection and which side was picked in the case of a surface. This information is returned in the callback structure, XintView3DCallbackStruct, returned by action
XmNpickCallback. This callback structure contains another structure of type XintView3DPickData that is described below:

    typedef struct {
                    XintVector3  point;          /* point that was picked  */
                    XintVector3  normal;         /* Normal at intersection */
                    XintVector3 *vertex;         /* Closest vertex picked  */
    } XintView3DPickData;

By default each object added to a View3D viewer can be picked. Marker objects however cannot be picked. Use function XintView3DSetPickable to control whether or not an object can be picked.

The following code sample (see file pick.c in directory examples) illustrates how to create a marker attached at the location that was picked. The marker's label is displayed remotely in the direction of the normal to the object.

    static void PickCallback(Widget widget, 
                             XintView3DMaterial *marker_material,
                             XintView3DCallbackStruct *cb)
    {
        static int count = 0;
        char string[16];
        XintView3DObject *marker;
        XintVector3      label_location;

        count++;
        sprintf(string, "marker %d", count);

        /* Create a marker object */
        label_location[0] = cb->pick_data.point[0] + 100. * 
                            cb->pick_data.normal[0];
        label_location[1] = cb->pick_data.point[1] + 100. *
                            cb->pick_data.normal[1];
        label_location[2] = cb->pick_data.point[2] + 100. * 
                            cb->pick_data.normal[2];
        marker = XintView3DCreateMarker("marker", XintOBJECT_MARKER_BOX,
                                        2.0, cb->pick_data.point, string,
                                        label_location, True, NULL);

       /* Add object to display */
       XintView3DAddObjectAndMaterial(widget, marker, marker_material, NULL);
    }

The output of example pick.c is shown below.


Figure 25: Picking example.