Build Better Software. Faster.
Visit our company site at: www.techsoft3d.com
 

White Papers Index

Implementing 'Snap To' Capabilities in your Application
Rajesh

'Snapping to Grid' implies confining the mouse input to a pre-defined 3D planar grid. This feature is extensively used in various applications typically in situations where the user is required to create a drawing or a sketch. In this article we will learn how to enable this feature in your HOOPS based application using the utility class HSnapGrid which is provided with HOOPS/MVO.

Let us take a simple operation - creating a sphere. We will take the default implementation of the operator (HOpCreateSphere in MVO) and enhance it to provide the 'snap to grid' feature.

1. Define the Snap-Grid.
Create a member object pointer of class
HSnapGrid as below.

	class HOpCreateSphereSnap : public HBaseOperator
	{
		...
	protected:

	   bool     m_bSnapToGrid;    /*Indicates if in snap mode*/
	   HSnapGrid * m_pSnapGrid;   /*To display a grid and snap moves to it */
	   HC_KEY      m_ScratchSeg;  /*Scratch segment for drawing temporary geometry*/
	   ...
	}

Define the plane and intervals for the grid. The example below defines a grid which lies in XY plane and has unit interval along both the axes.

	HOpCreateSphereSnap::HOpCreateSphereSnap
(HBaseView* view, int DoRepeat, int DoCapture, bool SnapToGrid) : HBaseOperator(view, DoRepeat, DoCapture) { ... if( m_bSnapToGrid ) { // create a grid object with grid along XY plane m_pSnapGrid = new HSnapGrid(view); HPoint origin(0, 0, 0); HPoint ref1(1, 0, 0); HPoint ref2(0, 1, 0); m_pSnapGrid->Create(origin, ref1, ref2, 0, 0); // create a scratch area for highlighting snapped point HC_Open_Segment_By_Key(m_pView->GetConstructionKey()); m_ScratchSeg = HC_KOpen_Segment("scratch segment"); HC_Flush_Geometry("."); HC_Set_Visibility("everything = off, markers = on"); HC_Set_Color("markers = blue"); HC_Close_Segment(); HC_Close_Segment(); m_pView->Update(); } }

Remember to destroy the HSnapGrid object in the destructor. Using this object we can snap any mouse input point on to the grid.

2. Identify the mouse input functions.
From the HOpCreateSphere.h we find following functions which provides with a mouse input.
virtual int OnNoButtonDownAndMove(HEventInfo &event);
virtual int OnLButtonDown(HEventInfo &event);
virtual int OnLButtonDownAndMove(HEventInfo &event);
virtual int OnLButtonUp(HEventInfo &event);
Each of this function recieves the mouse input location through the HEventInfo parameter. In the next step, we are going to convert this mouse location to the nearest point on the grid.

3. Use HSnapGrid object to snap mouse input to nearest point on the grid.
The function HSnapGrid::GetSnappedXXX takes a point and returns the snapped point. OnLButtonDown function below shows an example.

    int HOpCreateSphereSnap::OnLButtonDown(HEventInfo &event)
	{
		...
		if( m_bSnapToGrid )
	    {
				// get the world pos point and snap it
				HPoint this_pt = event.GetMouseWorldPos();
				m_pSnapGrid->GetSnappedWorldPos( this_pt );

				// highlight the snapped location
				HC_Open_Segment_By_Key(m_ScratchSeg);
			     HC_Flush_Geometry(".");
			     HC_Insert_Marker(this_pt.x, this_pt.y, this_pt.z);
				HC_Close_Segment();

				// reset the event with the snapped point
				event.SetWorldPos(event.GetType(), this_pt, event.GetFlags());
		}
		...
	}

How is it done?
The input location is projected onto the view plane. A ray is the created with the help of this point and original input location. The intersection of this ray and the grid plane gives a point on the grid plane. Finally this point is snapped to its closed grid point and returned. To display the grid, HSnapGrid uses HOOPS' Insert_Grid api.

Advanced Grid Manipulation
Various other methods of HSnapGrid allows the programmer to control various aspects of the grid. HSnapGrid::GetGridSegment returns the segment key in which the grid geometry is inserted. The programmer can set various attributes of this segment to set the display of the grid. Also, one can set the grid to be displayed on top by using the api HSnapGrid::SetOnTop.

Fig. 1: The mouse point snapped on to the grid for input as the center of the sphere


Fig. 2: The mouse point snapped on to the grid for second input as a point on the sphere.

Fig. 3: The output sphere.

 

 
 

 

 

 

 

©2004-06 Tech Soft 3D All Rights Reserved. Privacy | Legal