0026511: Build fails with VTK 6.3rc1
[occt.git] / src / IVtkTools / IVtkTools_ShapePicker.cxx
1 // Created on: 2011-10-27 
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 <IVtkTools_ShapePicker.hxx>
17 #include <IVtkTools_ShapeObject.hxx>
18 #include <IVtkVTK_View.hxx>
19 #include <IVtkOCC_Shape.hxx>
20 #include <vtkCommand.h>
21 #include <vtkObjectFactory.h>
22 #include <vtkRenderer.h>
23 #include <vtkActorCollection.h>
24
25 //! @class IVtkTools_ShapePicker
26 //! VTK picker implementation for OCCT shapes.
27 //! Can pick either whole shapes or sub-shapes.
28 //! The kind of selectable entities is defined by the current selection mode.
29 //! NOTE: For performance reasons, setRenderer() method should be called in advance,
30 //! before the user starts to select interactively, in order for the OCCT selection
31 //! algorithm to prepare its internal selection data.
32
33 vtkStandardNewMacro(IVtkTools_ShapePicker);
34
35 //============================================================================
36 //  Method: IVtkTools_ShapePicker
37 // Purpose: Constructs the picker with empty renderer and ready for point selection.
38 //============================================================================
39 IVtkTools_ShapePicker::IVtkTools_ShapePicker()
40 : myRenderer (0),
41   myIsRectSelection (false)
42 {
43   myOccPickerAlgo = new IVtkOCC_ShapePickerAlgo();
44 }
45
46 //============================================================================
47 //  Method: ~IVtkTools_ShapePicker
48 // Purpose: Destructor
49 //============================================================================
50 IVtkTools_ShapePicker::~IVtkTools_ShapePicker()
51 {
52 }
53
54 //============================================================================
55 //  Method: SetTolerance
56 // Purpose: Setter for tolerance of picking.
57 //============================================================================
58 void IVtkTools_ShapePicker::SetTolerance (float theTolerance )
59 {
60   myTolerance = theTolerance;
61 }
62
63 //============================================================================
64 //  Method: GetTolerance
65 // Purpose: Getter for tolerance of picking.
66 //============================================================================
67 float IVtkTools_ShapePicker::GetTolerance( ) const
68 {
69   return myTolerance;
70 }
71
72 //============================================================================
73 //  Method: convertDisplayToWorld
74 // Purpose: Convert display coordinates to world coordinates
75 //============================================================================
76 bool IVtkTools_ShapePicker::convertDisplayToWorld (vtkRenderer *theRenderer,
77                                                    double theDisplayCoord[3],
78                                                    double theWorldCoord[3])
79 {
80   // Convert the selection point into world coordinates.
81   theRenderer->SetDisplayPoint (theDisplayCoord[0], theDisplayCoord[1], theDisplayCoord[2]);
82   theRenderer->DisplayToWorld();
83
84   double* const aCoords = theRenderer->GetWorldPoint();
85   if (aCoords[3] == 0.0)
86   {
87     return false;
88   }
89
90   for (Standard_Integer anI = 0; anI < 3; anI++)
91   {
92     theWorldCoord[anI] = aCoords[anI] / aCoords[3];
93   }
94   return true;
95 }
96
97 //============================================================================
98 // Method:  Pick
99 // Purpose: Pick entities in the given point.
100 //============================================================================
101 int IVtkTools_ShapePicker::Pick (double theX, double theY, double /*theZ*/, vtkRenderer *theRenderer)
102 {
103   double aPos[2] = {theX, theY};
104   myIsRectSelection = false;
105   myIsPolySelection = false;
106   return pick (aPos, theRenderer);
107 }
108
109 //============================================================================
110 //  Method: pick
111 // Purpose: Pick entities in the given rectangle area.
112 //============================================================================
113 int IVtkTools_ShapePicker::Pick (double theXPMin, double theYPMin, double theXPMax, double theYPMax,
114                                  vtkRenderer *theRenderer)
115 {
116   double aPos[4] = {theXPMin, theYPMin, theXPMax, theYPMax};
117   myIsRectSelection = true;
118   myIsPolySelection = false;
119   return pick (aPos, theRenderer);
120 }
121 //============================================================================
122 //  Method: pick
123 // Purpose: Pick entities in the given polygonal area.
124 //============================================================================
125 int IVtkTools_ShapePicker::Pick (double thePoly[][3], const int theNbPoints,
126                                  vtkRenderer *theRenderer)
127 {
128   myIsRectSelection = false;
129   myIsPolySelection = true;
130   return pick ((double*)thePoly, theRenderer, theNbPoints);
131 }
132
133 //============================================================================
134 //  Method: pick
135 // Purpose: Pick entities in the given point or area.
136 //============================================================================
137 int IVtkTools_ShapePicker::pick (double* thePos,
138                                  vtkRenderer *theRenderer,
139                                  const int theNbPoints)
140 {
141  //  Initialize picking process
142   Initialize();
143
144   // Emit StartPickEvent for observer callbacks (if any)
145   InvokeEvent(vtkCommand::StartPickEvent, NULL);
146
147   vtkRenderer* aRenderer;
148   if (theRenderer == NULL)
149   {
150     aRenderer = myRenderer; // by default use own renderer
151   }
152   else
153   {
154     aRenderer = theRenderer;
155   }
156   doPickImpl (thePos, aRenderer, theNbPoints);
157
158   // Emit EndPickEvent for observer callbacks (if any)
159   InvokeEvent(vtkCommand::EndPickEvent, NULL);
160
161   return myOccPickerAlgo->NbPicked();
162 }
163
164 //============================================================================
165 //  Method: doPickImpl
166 // Purpose: Implementation of picking algorithm.
167 //============================================================================
168 void IVtkTools_ShapePicker::doPickImpl (double* thePos,
169                                         vtkRenderer* theRenderer, 
170                                         const int theNbPoints)
171 {
172   // Make sure the correct renderer is used
173   SetRenderer (theRenderer);
174
175   if (myIsPolySelection)
176   {
177     myOccPickerAlgo->Pick ((double**)thePos, theNbPoints);
178   }
179   else if (myIsRectSelection)
180   {
181     myOccPickerAlgo->Pick (thePos[0], thePos[1], thePos[2], thePos[3]);
182   }
183   else
184   {
185     myOccPickerAlgo->Pick (thePos[0], thePos[1]);
186   }
187 }
188
189 //============================================================================
190 //  Method: SetRenderer
191 // Purpose: Sets the renderer to be used by OCCT selection algorithm
192 //============================================================================
193 void IVtkTools_ShapePicker::SetRenderer (vtkRenderer* theRenderer)
194 {
195   if (theRenderer == myRenderer)
196   {
197     return;
198     // In this case we should not do anything.
199     // In the worth case we need to update picker algorithm (view er selector and projection options)
200     // If any needs this , call myOccPickerAlgo->Modified();
201   }
202
203   myRenderer = theRenderer;
204   IVtkVTK_View::Handle aView = new IVtkVTK_View (myRenderer);
205   myOccPickerAlgo->SetView (aView);
206 }
207
208 //============================================================================
209 //  Method: SetAreaSelection
210 // Purpose: Sets area selection on/off
211 //============================================================================
212 void IVtkTools_ShapePicker::SetAreaSelection (bool theIsOn)
213 {
214   myIsRectSelection = theIsOn;
215 }
216
217 //============================================================================
218 //  Method: GetSelectionModes
219 // Purpose: Get activated selection modes for a shape.
220 //============================================================================
221 IVtk_SelectionModeList IVtkTools_ShapePicker::GetSelectionModes (
222                                               const IVtk_IShape::Handle& theShape) const
223 {
224   return myOccPickerAlgo->GetSelectionModes (theShape);
225 }
226
227 //============================================================================
228 //  Method: GetSelectionModes
229 // Purpose: Get activated selection modes for a shape actor.
230 //============================================================================
231 IVtk_SelectionModeList IVtkTools_ShapePicker::GetSelectionModes (
232                                               vtkActor* theShapeActor) const
233 {
234   IVtk_SelectionModeList aRes;
235   IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
236   if (!aShape.IsNull())
237   {
238     aRes = myOccPickerAlgo->GetSelectionModes (aShape);
239   }
240   return aRes;
241 }
242
243 //============================================================================
244 //  Method: SetSelectionMode
245 // Purpose: Turn on/off a selection mode for a shape.
246 //============================================================================
247 void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_IShape::Handle& theShape,
248                                               const IVtk_SelectionMode   theMode,
249                                               const bool                 theIsTurnOn) const
250 {
251   myOccPickerAlgo->SetSelectionMode (theShape, theMode, theIsTurnOn);
252 }
253
254 //============================================================================
255 //  Method: SetSelectionMode
256 // Purpose: Turn on/off a selection mode for a shape actor.
257 //============================================================================
258 void IVtkTools_ShapePicker::SetSelectionMode (vtkActor*                theShapeActor,
259                                               const IVtk_SelectionMode theMode,
260                                               const bool               theIsTurnOn) const
261 {
262   IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
263   if (!aShape.IsNull())
264   {
265     myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
266   }
267 }
268
269 //============================================================================
270 //  Method: SetSelectionMode
271 // Purpose: Sets the current selection mode for all visible shape objects.
272 //============================================================================
273 void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_SelectionMode theMode, 
274                                               const bool               theIsTurnOn) const
275 {
276   if (myRenderer)
277   {
278     // Obtain all OccShapes displayed and activate the specified selection mode
279     vtkActorCollection *anActors = myRenderer->GetActors();
280     anActors->InitTraversal();
281     while ( vtkActor* anActor = anActors->GetNextActor() )
282     {
283       if (anActor->GetPickable() && anActor->GetVisibility())
284       {
285         if (anActor->GetMapper())
286         {
287           IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
288           if (!aShape.IsNull())
289           {
290             myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
291           }
292         }
293       }
294     }
295   }
296 }
297
298 //============================================================================
299 //  Method: GetPickedShapesIds
300 // Purpose: Access to the list of top-level shapes picked.
301 //============================================================================
302 IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedShapesIds (bool theIsAll) const
303 {
304   if (theIsAll || myIsRectSelection )
305   {
306     return myOccPickerAlgo->ShapesPicked();
307   }
308
309   IVtk_ShapeIdList aRes;
310   IVtk_ShapeIdList aPicked = myOccPickerAlgo->ShapesPicked();
311   if (!aPicked.IsEmpty())
312   {
313     aRes.Append (aPicked.First());
314   }
315   return aRes;
316 }
317
318 //============================================================================
319 //  Method: GetPickedSubShapesIds
320 // Purpose: Access to the list of sub-shapes ids picked.
321 //============================================================================
322 IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedSubShapesIds (const IVtk_IdType theId, bool theIsAll) const
323 {
324   IVtk_ShapeIdList aRes;
325   if (theIsAll)
326   {
327     myOccPickerAlgo->SubShapesPicked (theId,aRes);
328   }
329   else
330   {
331     IVtk_ShapeIdList aList;
332     myOccPickerAlgo->SubShapesPicked (theId, aList);
333     if (!aList.IsEmpty())
334     {
335       aRes.Append (aList.First());
336     }
337   }
338   return aRes;
339 }
340
341 //============================================================================
342 //  Method: GetPickedActors
343 // Purpose: Access to the list of actors picked.
344 //============================================================================
345 vtkActorCollection* IVtkTools_ShapePicker::GetPickedActors (bool theIsAll) const
346 {
347   vtkActorCollection* aRes = vtkActorCollection::New();
348   IVtk_ShapeIdList anIds = GetPickedShapesIds (theIsAll);
349   if (myRenderer)
350   {
351     // Obtain all actors whose source shape ids are within selected ids.
352     vtkActorCollection *anActors = myRenderer->GetActors();
353     anActors->InitTraversal();
354     while ( vtkActor* anActor = anActors->GetNextActor() )
355     {
356       if (anActor->GetPickable() && anActor->GetVisibility())
357       {
358         if (anActor->GetMapper())
359         {
360           IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
361           if (!aShape.IsNull())
362           {
363             for (IVtk_ShapeIdList::Iterator anIt (anIds); anIt.More(); anIt.Next())
364             {
365               if (aShape->GetId() == anIt.Value())
366               {
367                 aRes->AddItem (anActor);
368               }
369             }
370           }
371         }
372       }
373     }
374   }
375   return aRes;
376 }