0026159: Visualization - revise tolerance implementation for selection
[occt.git] / src / IVtkOCC / IVtkOCC_ViewerSelector.cxx
1 // Created on: 2011-10-20 
2 // Created by: Roman KOZLOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS 
4 // 
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <IVtkOCC_ViewerSelector.hxx>
17 #include <Select3D_SensitiveBox.hxx>
18 #include <TColgp_Array1OfPnt2d.hxx>
19 #include <gp_Quaternion.hxx>
20 #include <Graphic3d_Camera.hxx>
21
22 IMPLEMENT_STANDARD_HANDLE( IVtkOCC_ViewerSelector, SelectMgr_ViewerSelector )
23 IMPLEMENT_STANDARD_RTTIEXT( IVtkOCC_ViewerSelector, SelectMgr_ViewerSelector )
24
25 //============================================================================
26 // Method:  Constructor
27 // Purpose:
28 //============================================================================
29 IVtkOCC_ViewerSelector::IVtkOCC_ViewerSelector()
30 : SelectMgr_ViewerSelector(),
31 myPixTol(2),
32 myToUpdateTol(Standard_True) {}
33
34 //============================================================================
35 // Method:  Pick
36 // Purpose: Implements point picking
37 //============================================================================
38 void IVtkOCC_ViewerSelector::Pick (const Standard_Integer theXPix,
39                                    const Standard_Integer theYPix,
40                                    const IVtk_IView::Handle&    theView)
41 {
42   if (myToUpdateTol)
43   {
44     // Compute and set a sensitivity tolerance according to the renderer (viewport).
45     // TODO: Think if this works well in perspective view...'cause result depends
46     // on position on the screen, but we always use the point close to the
47     // screen's origin...
48     mySelectingVolumeMgr.SetPixelTolerance (myPixTol);
49
50     myToUpdateTol = Standard_False;
51   }
52
53   Standard_Integer aWidth = 0, aHeight = 0;
54   Graphic3d_Mat4d aProj, anOrient;
55   Standard_Boolean isOrthographic = Standard_False;
56   Standard_Real aX = RealLast(), aY = RealLast();
57   Standard_Real aVpWidth = RealLast(), aVpHeight = RealLast();
58
59   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Point);
60   theView->GetCamera (aProj, anOrient, isOrthographic);
61   mySelectingVolumeMgr.SetCamera (aProj, anOrient, isOrthographic);
62
63   theView->GetWindowSize (aWidth, aHeight);
64   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
65
66   theView->GetViewport (aX, aY, aVpWidth, aVpHeight);
67   mySelectingVolumeMgr.SetViewport (aX, aY, aVpWidth, aVpHeight);
68
69   gp_Pnt2d aMousePos (static_cast<Standard_Real> (theXPix),
70                       static_cast<Standard_Real> (theYPix));
71   mySelectingVolumeMgr.BuildSelectingVolume (aMousePos);
72
73   TraverseSensitives();
74 }
75
76 //============================================================================
77 // Method:  Pick
78 // Purpose: Picking by rectangle
79 //============================================================================
80 void IVtkOCC_ViewerSelector::Pick (const Standard_Integer    theXMin,
81                                    const Standard_Integer    theYMin,
82                                    const Standard_Integer    theXMax,
83                                    const Standard_Integer    theYMax,
84                                    const IVtk_IView::Handle& theView)
85 {
86   if (myToUpdateTol)
87   {
88     // Compute and set a sensitivity tolerance according to the renderer (viewport).
89     // TODO: Think if this works well in perspective view...'cause result depends
90     // on position on the screen, but we always use the point close to the
91     // screen's origin...
92     mySelectingVolumeMgr.SetPixelTolerance (myPixTol);
93
94     myToUpdateTol = Standard_False;
95   }
96
97   Standard_Integer aWidth = 0, aHeight = 0;
98   Graphic3d_Mat4d aProj, anOrient;
99   Standard_Boolean isOrthographic = Standard_False;
100   Standard_Real aX = RealLast(), aY = RealLast();
101   Standard_Real aVpWidth = RealLast(), aVpHeight = RealLast();
102
103   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Box);
104   theView->GetCamera (aProj, anOrient, isOrthographic);
105   mySelectingVolumeMgr.SetCamera (aProj, anOrient, isOrthographic);
106
107   theView->GetWindowSize (aWidth, aHeight);
108   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
109
110   theView->GetViewport (aX, aY, aVpWidth, aVpHeight);
111   mySelectingVolumeMgr.SetViewport (aX, aY, aVpWidth, aVpHeight);
112
113   gp_Pnt2d aMinMousePos (static_cast<Standard_Real> (theXMin),
114                          static_cast<Standard_Real> (theYMin));
115   gp_Pnt2d aMaxMousePos (static_cast<Standard_Real> (theXMax),
116                          static_cast<Standard_Real> (theYMax));
117
118   mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos,
119                                              aMaxMousePos);
120
121   TraverseSensitives();
122 }
123
124 //============================================================================
125 // Method:  Pick
126 // Purpose:
127 //============================================================================
128 void IVtkOCC_ViewerSelector::Pick (double**                  thePoly,
129                                    const int                 theNbPoints,
130                                    const IVtk_IView::Handle& theView)
131 {
132   TColgp_Array1OfPnt2d aPolyline (1, theNbPoints);
133
134   if (myToUpdateTol)
135   {
136     // Compute and set a sensitivity tolerance according to the renderer (viewport).
137     // TODO: Think if this works well in perspective view...'cause result depends
138     // on position on the screen, but we always use the point close to the
139     // screen's origin...
140     mySelectingVolumeMgr.SetPixelTolerance (myPixTol);
141
142     myToUpdateTol = Standard_False;
143   }
144
145   // Build TColgp_Array1OfPnt2d from input array of doubles
146   gp_XYZ aWorldPnt;
147
148   for (Standard_Integer anIt = 0; anIt < theNbPoints; anIt++)
149   {
150     gp_XY aDispPnt = thePoly[anIt][2] != 0 ? gp_XY (thePoly[anIt][0] / thePoly[anIt][2], thePoly[anIt][1] / thePoly[anIt][2])
151                                            : gp_XY (thePoly[anIt][0], thePoly[anIt][1]);
152     aPolyline.SetValue (anIt + 1, aDispPnt);
153   }
154
155   Standard_Integer aWidth = 0, aHeight = 0;
156   Graphic3d_Mat4d aProj, anOrient;
157   Standard_Boolean isOrthographic = Standard_False;
158   Standard_Real aX = RealLast(), aY = RealLast();
159   Standard_Real aVpWidth = RealLast(), aVpHeight = RealLast();
160
161   mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Polyline);
162   theView->GetCamera (aProj, anOrient, isOrthographic);
163   mySelectingVolumeMgr.SetCamera (aProj, anOrient, isOrthographic);
164
165   theView->GetWindowSize (aWidth, aHeight);
166   mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
167
168   theView->GetViewport (aX, aY, aVpWidth, aVpHeight);
169   mySelectingVolumeMgr.SetViewport (aX, aY, aVpWidth, aVpHeight);
170
171   mySelectingVolumeMgr.BuildSelectingVolume (aPolyline);
172
173   TraverseSensitives();
174 }
175
176 //============================================================================
177 // Method:  Activate
178 // Purpose: Activates the given selection
179 //============================================================================
180 void IVtkOCC_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
181 {
182   for (theSelection->Init(); theSelection->More(); theSelection->Next())
183   {
184     theSelection->Sensitive()->SetActiveForSelection();
185   }
186
187   theSelection->SetSelectionState (SelectMgr_SOS_Activated);
188
189   myTolerances.Add (theSelection->Sensitivity());
190   mytolerance = myTolerances.Tolerance();
191   myToUpdateTolerance = Standard_True;
192 }
193
194 //============================================================================
195 // Method:  Deactivate
196 // Purpose: Deactivate the given selection
197 //============================================================================
198 void IVtkOCC_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
199 {
200   for (theSelection->Init(); theSelection->More(); theSelection->Next())
201   {
202     theSelection->Sensitive()->ResetSelectionActiveStatus();
203   }
204
205   theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
206
207   myTolerances.Decrement (theSelection->Sensitivity());
208   mytolerance = myTolerances.Tolerance();
209   myToUpdateTolerance = Standard_True;
210 }