1 // Created on: 2011-10-27
2 // Created by: Roman KOZLOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
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>
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.
33 vtkStandardNewMacro(IVtkTools_ShapePicker);
35 //============================================================================
36 // Method: IVtkTools_ShapePicker
37 // Purpose: Constructs the picker with empty renderer and ready for point selection.
38 //============================================================================
39 IVtkTools_ShapePicker::IVtkTools_ShapePicker()
41 myIsRectSelection (false)
43 myOccPickerAlgo = new IVtkOCC_ShapePickerAlgo();
46 //============================================================================
47 // Method: ~IVtkTools_ShapePicker
48 // Purpose: Destructor
49 //============================================================================
50 IVtkTools_ShapePicker::~IVtkTools_ShapePicker()
54 //============================================================================
55 // Method: SetTolerance
56 // Purpose: Setter for tolerance of picking.
57 //============================================================================
58 void IVtkTools_ShapePicker::SetTolerance (float theTolerance )
60 myTolerance = theTolerance;
63 //============================================================================
64 // Method: GetTolerance
65 // Purpose: Getter for tolerance of picking.
66 //============================================================================
67 float IVtkTools_ShapePicker::GetTolerance( ) const
72 //============================================================================
73 // Method: convertDisplayToWorld
74 // Purpose: Convert display coordinates to world coordinates
75 //============================================================================
76 bool IVtkTools_ShapePicker::convertDisplayToWorld (vtkRenderer *theRenderer,
77 vtkFloatingPointType theDisplayCoord[3],
78 vtkFloatingPointType theWorldCoord[3])
80 // Convert the selection point into world coordinates.
81 theRenderer->SetDisplayPoint (theDisplayCoord[0], theDisplayCoord[1], theDisplayCoord[2]);
82 theRenderer->DisplayToWorld();
84 vtkFloatingPointType* const aCoords = theRenderer->GetWorldPoint();
85 if (aCoords[3] == 0.0)
90 for (Standard_Integer anI = 0; anI < 3; anI++)
92 theWorldCoord[anI] = aCoords[anI] / aCoords[3];
97 //============================================================================
99 // Purpose: Pick entities in the given point.
100 //============================================================================
101 int IVtkTools_ShapePicker::Pick (double theX, double theY, double /*theZ*/, vtkRenderer *theRenderer)
103 double aPos[2] = {theX, theY};
104 myIsRectSelection = false;
105 myIsPolySelection = false;
106 return pick (aPos, theRenderer);
109 //============================================================================
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)
116 double aPos[4] = {theXPMin, theYPMin, theXPMax, theYPMax};
117 myIsRectSelection = true;
118 myIsPolySelection = false;
119 return pick (aPos, theRenderer);
121 //============================================================================
123 // Purpose: Pick entities in the given polygonal area.
124 //============================================================================
125 int IVtkTools_ShapePicker::Pick (double thePoly[][3], const int theNbPoints,
126 vtkRenderer *theRenderer)
128 myIsRectSelection = false;
129 myIsPolySelection = true;
130 return pick ((double*)thePoly, theRenderer, theNbPoints);
133 //============================================================================
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)
141 // Initialize picking process
144 // Emit StartPickEvent for observer callbacks (if any)
145 InvokeEvent(vtkCommand::StartPickEvent, NULL);
147 vtkRenderer* aRenderer;
148 if (theRenderer == NULL)
150 aRenderer = myRenderer; // by default use own renderer
154 aRenderer = theRenderer;
156 doPickImpl (thePos, aRenderer, theNbPoints);
158 // Emit EndPickEvent for observer callbacks (if any)
159 InvokeEvent(vtkCommand::EndPickEvent, NULL);
161 return myOccPickerAlgo->NbPicked();
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)
172 // Make sure the correct renderer is used
173 SetRenderer (theRenderer);
175 if (myIsPolySelection)
177 myOccPickerAlgo->Pick ((double**)thePos, theNbPoints);
179 else if (myIsRectSelection)
181 myOccPickerAlgo->Pick (thePos[0], thePos[1], thePos[2], thePos[3]);
185 myOccPickerAlgo->Pick (thePos[0], thePos[1]);
189 //============================================================================
190 // Method: SetRenderer
191 // Purpose: Sets the renderer to be used by OCCT selection algorithm
192 //============================================================================
193 void IVtkTools_ShapePicker::SetRenderer (vtkRenderer* theRenderer)
195 if (theRenderer == myRenderer)
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();
203 myRenderer = theRenderer;
204 IVtkVTK_View::Handle aView = new IVtkVTK_View (myRenderer);
205 myOccPickerAlgo->SetView (aView);
208 //============================================================================
209 // Method: SetAreaSelection
210 // Purpose: Sets area selection on/off
211 //============================================================================
212 void IVtkTools_ShapePicker::SetAreaSelection (bool theIsOn)
214 myIsRectSelection = theIsOn;
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
224 return myOccPickerAlgo->GetSelectionModes (theShape);
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
234 IVtk_SelectionModeList aRes;
235 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
236 if (!aShape.IsNull())
238 aRes = myOccPickerAlgo->GetSelectionModes (aShape);
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
251 myOccPickerAlgo->SetSelectionMode (theShape, theMode, theIsTurnOn);
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
262 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
263 if (!aShape.IsNull())
265 myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
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
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() )
283 if (anActor->GetPickable() && anActor->GetVisibility())
285 if (anActor->GetMapper())
287 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
288 if (!aShape.IsNull())
290 myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
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
304 if (theIsAll || myIsRectSelection )
306 return myOccPickerAlgo->ShapesPicked();
309 IVtk_ShapeIdList aRes;
310 IVtk_ShapeIdList aPicked = myOccPickerAlgo->ShapesPicked();
311 if (!aPicked.IsEmpty())
313 aRes.Append (aPicked.First());
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
324 IVtk_ShapeIdList aRes;
327 myOccPickerAlgo->SubShapesPicked (theId,aRes);
331 IVtk_ShapeIdList aList;
332 myOccPickerAlgo->SubShapesPicked (theId, aList);
333 if (!aList.IsEmpty())
335 aRes.Append (aList.First());
341 //============================================================================
342 // Method: GetPickedActors
343 // Purpose: Access to the list of actors picked.
344 //============================================================================
345 vtkActorCollection* IVtkTools_ShapePicker::GetPickedActors (bool theIsAll) const
347 vtkActorCollection* aRes = vtkActorCollection::New();
348 IVtk_ShapeIdList anIds = GetPickedShapesIds (theIsAll);
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() )
356 if (anActor->GetPickable() && anActor->GetVisibility())
358 if (anActor->GetMapper())
360 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
361 if (!aShape.IsNull())
363 for (IVtk_ShapeIdList::Iterator anIt (anIds); anIt.More(); anIt.Next())
365 if (aShape->GetId() == anIt.Value())
367 aRes->AddItem (anActor);