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>
20 // prevent disabling some MSVC warning messages by VTK headers
24 #include <vtkCommand.h>
25 #include <vtkObjectFactory.h>
26 #include <vtkRenderer.h>
27 #include <vtkActorCollection.h>
32 //! @class IVtkTools_ShapePicker
33 //! VTK picker implementation for OCCT shapes.
34 //! Can pick either whole shapes or sub-shapes.
35 //! The kind of selectable entities is defined by the current selection mode.
36 //! NOTE: For performance reasons, setRenderer() method should be called in advance,
37 //! before the user starts to select interactively, in order for the OCCT selection
38 //! algorithm to prepare its internal selection data.
40 vtkStandardNewMacro(IVtkTools_ShapePicker)
42 //============================================================================
43 // Method: IVtkTools_ShapePicker
44 // Purpose: Constructs the picker with empty renderer and ready for point selection.
45 //============================================================================
46 IVtkTools_ShapePicker::IVtkTools_ShapePicker()
48 myIsRectSelection (false)
50 myOccPickerAlgo = new IVtkOCC_ShapePickerAlgo();
53 //============================================================================
54 // Method: ~IVtkTools_ShapePicker
55 // Purpose: Destructor
56 //============================================================================
57 IVtkTools_ShapePicker::~IVtkTools_ShapePicker()
61 //============================================================================
62 // Method: SetTolerance
63 // Purpose: Setter for tolerance of picking.
64 //============================================================================
65 void IVtkTools_ShapePicker::SetTolerance (float theTolerance )
67 myTolerance = theTolerance;
70 //============================================================================
71 // Method: GetTolerance
72 // Purpose: Getter for tolerance of picking.
73 //============================================================================
74 float IVtkTools_ShapePicker::GetTolerance( ) const
79 //============================================================================
80 // Method: convertDisplayToWorld
81 // Purpose: Convert display coordinates to world coordinates
82 //============================================================================
83 bool IVtkTools_ShapePicker::convertDisplayToWorld (vtkRenderer *theRenderer,
84 double theDisplayCoord[3],
85 double theWorldCoord[3])
87 // Convert the selection point into world coordinates.
88 theRenderer->SetDisplayPoint (theDisplayCoord[0], theDisplayCoord[1], theDisplayCoord[2]);
89 theRenderer->DisplayToWorld();
92 theRenderer->GetWorldPoint(aCoords);
93 if (aCoords[3] == 0.0)
98 for (Standard_Integer anI = 0; anI < 3; anI++)
100 theWorldCoord[anI] = aCoords[anI] / aCoords[3];
106 //============================================================================
108 // Purpose: Pick entities in the given point.
109 //============================================================================
110 int IVtkTools_ShapePicker::Pick (double theX, double theY, double /*theZ*/, vtkRenderer *theRenderer)
112 double aPos[2] = {theX, theY};
113 myIsRectSelection = false;
114 myIsPolySelection = false;
115 return pick (aPos, theRenderer);
118 //============================================================================
120 // Purpose: Pick entities in the given rectangle area.
121 //============================================================================
122 int IVtkTools_ShapePicker::Pick (double theXPMin, double theYPMin, double theXPMax, double theYPMax,
123 vtkRenderer *theRenderer)
125 double aPos[4] = {theXPMin, theYPMin, theXPMax, theYPMax};
126 myIsRectSelection = true;
127 myIsPolySelection = false;
128 return pick (aPos, theRenderer);
130 //============================================================================
132 // Purpose: Pick entities in the given polygonal area.
133 //============================================================================
134 int IVtkTools_ShapePicker::Pick (double thePoly[][3], const int theNbPoints,
135 vtkRenderer *theRenderer)
137 myIsRectSelection = false;
138 myIsPolySelection = true;
139 return pick ((double*)thePoly, theRenderer, theNbPoints);
142 //============================================================================
144 // Purpose: Pick entities in the given point or area.
145 //============================================================================
146 int IVtkTools_ShapePicker::pick (double* thePos,
147 vtkRenderer *theRenderer,
148 const int theNbPoints)
150 // Initialize picking process
153 // Emit StartPickEvent for observer callbacks (if any)
154 InvokeEvent(vtkCommand::StartPickEvent, NULL);
156 vtkSmartPointer<vtkRenderer> aRenderer;
157 if (theRenderer == NULL)
159 aRenderer = myRenderer; // by default use own renderer
163 aRenderer = theRenderer;
165 doPickImpl (thePos, aRenderer, theNbPoints);
167 // Emit EndPickEvent for observer callbacks (if any)
168 InvokeEvent(vtkCommand::EndPickEvent, NULL);
170 return myOccPickerAlgo->NbPicked();
173 //============================================================================
174 // Method: doPickImpl
175 // Purpose: Implementation of picking algorithm.
176 //============================================================================
177 void IVtkTools_ShapePicker::doPickImpl (double* thePos,
178 vtkRenderer* theRenderer,
179 const int theNbPoints)
181 // Make sure the correct renderer is used
182 SetRenderer (theRenderer);
184 if (myIsPolySelection)
186 myOccPickerAlgo->Pick ((double**)thePos, theNbPoints);
188 else if (myIsRectSelection)
190 myOccPickerAlgo->Pick (thePos[0], thePos[1], thePos[2], thePos[3]);
194 myOccPickerAlgo->Pick (thePos[0], thePos[1]);
197 PickPosition[0] = myOccPickerAlgo->TopPickedPoint().X();
198 PickPosition[1] = myOccPickerAlgo->TopPickedPoint().Y();
199 PickPosition[2] = myOccPickerAlgo->TopPickedPoint().Z();
202 //============================================================================
203 // Method: SetRenderer
204 // Purpose: Sets the renderer to be used by OCCT selection algorithm
205 //============================================================================
206 void IVtkTools_ShapePicker::SetRenderer (vtkRenderer* theRenderer)
208 if (theRenderer == myRenderer.GetPointer())
211 // In this case we should not do anything.
212 // In the worth case we need to update picker algorithm (view er selector and projection options)
213 // If any needs this , call myOccPickerAlgo->Modified();
216 myRenderer = theRenderer;
217 IVtkVTK_View::Handle aView = new IVtkVTK_View (myRenderer);
218 myOccPickerAlgo->SetView (aView);
221 //============================================================================
222 // Method: SetAreaSelection
223 // Purpose: Sets area selection on/off
224 //============================================================================
225 void IVtkTools_ShapePicker::SetAreaSelection (bool theIsOn)
227 myIsRectSelection = theIsOn;
230 //============================================================================
231 // Method: GetSelectionModes
232 // Purpose: Get activated selection modes for a shape.
233 //============================================================================
234 IVtk_SelectionModeList IVtkTools_ShapePicker::GetSelectionModes (
235 const IVtk_IShape::Handle& theShape) const
237 return myOccPickerAlgo->GetSelectionModes (theShape);
240 //============================================================================
241 // Method: GetSelectionModes
242 // Purpose: Get activated selection modes for a shape actor.
243 //============================================================================
244 IVtk_SelectionModeList IVtkTools_ShapePicker::GetSelectionModes (
245 vtkActor* theShapeActor) const
247 IVtk_SelectionModeList aRes;
248 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
249 if (!aShape.IsNull())
251 aRes = myOccPickerAlgo->GetSelectionModes (aShape);
256 //============================================================================
257 // Method: SetSelectionMode
258 // Purpose: Turn on/off a selection mode for a shape.
259 //============================================================================
260 void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_IShape::Handle& theShape,
261 const IVtk_SelectionMode theMode,
262 const bool theIsTurnOn) const
264 myOccPickerAlgo->SetSelectionMode (theShape, theMode, theIsTurnOn);
267 //============================================================================
268 // Method: SetSelectionMode
269 // Purpose: Turn on/off a selection mode for a shape actor.
270 //============================================================================
271 void IVtkTools_ShapePicker::SetSelectionMode (vtkActor* theShapeActor,
272 const IVtk_SelectionMode theMode,
273 const bool theIsTurnOn) const
275 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
276 if (!aShape.IsNull())
278 myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
282 //============================================================================
283 // Method: SetSelectionMode
284 // Purpose: Sets the current selection mode for all visible shape objects.
285 //============================================================================
286 void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_SelectionMode theMode,
287 const bool theIsTurnOn) const
289 if (myRenderer.GetPointer() != NULL)
291 // Obtain all OccShapes displayed and activate the specified selection mode
292 vtkSmartPointer<vtkActorCollection> anActors = myRenderer->GetActors();
293 anActors->InitTraversal();
294 vtkSmartPointer<vtkActor> anActor = anActors->GetNextActor();
295 while ( anActor.GetPointer() != NULL )
297 if (anActor->GetPickable() && anActor->GetVisibility())
299 if (anActor->GetMapper())
301 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
302 if (!aShape.IsNull())
304 myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
308 anActor = anActors->GetNextActor();
313 //============================================================================
314 // Method: GetPickedShapesIds
315 // Purpose: Access to the list of top-level shapes picked.
316 //============================================================================
317 IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedShapesIds (bool theIsAll) const
319 if (theIsAll || myIsRectSelection )
321 return myOccPickerAlgo->ShapesPicked();
324 IVtk_ShapeIdList aRes;
325 IVtk_ShapeIdList aPicked = myOccPickerAlgo->ShapesPicked();
326 if (!aPicked.IsEmpty())
328 aRes.Append (aPicked.First());
333 //============================================================================
334 // Method: RemoveSelectableActor
335 // Purpose: Remove selectable object from the picker (from internal maps).
336 //============================================================================
337 void IVtkTools_ShapePicker::RemoveSelectableObject(const IVtk_IShape::Handle& theShape)
339 myOccPickerAlgo->RemoveSelectableObject(theShape);
342 //============================================================================
343 // Method: RemoveSelectableActor
344 // Purpose: Remove selectable object from the picker (from internal maps).
345 //============================================================================
346 void IVtkTools_ShapePicker::RemoveSelectableActor(vtkActor* theShapeActor)
348 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape(theShapeActor);
349 if (!aShape.IsNull())
351 RemoveSelectableObject(aShape);
355 //============================================================================
356 // Method: GetPickedSubShapesIds
357 // Purpose: Access to the list of sub-shapes ids picked.
358 //============================================================================
359 IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedSubShapesIds (const IVtk_IdType theId, bool theIsAll) const
361 IVtk_ShapeIdList aRes;
364 myOccPickerAlgo->SubShapesPicked (theId, aRes);
368 IVtk_ShapeIdList aList;
369 myOccPickerAlgo->SubShapesPicked (theId, aList);
370 if (!aList.IsEmpty())
372 aRes.Append (aList.First());
378 //============================================================================
379 // Method: GetPickedActors
380 // Purpose: Access to the list of actors picked.
381 //============================================================================
382 vtkSmartPointer<vtkActorCollection> IVtkTools_ShapePicker::GetPickedActors (bool theIsAll) const
384 vtkSmartPointer<vtkActorCollection> aRes = vtkSmartPointer<vtkActorCollection>::New();
385 IVtk_ShapeIdList anIds = GetPickedShapesIds (theIsAll);
386 if (myRenderer.GetPointer() != NULL)
388 // Obtain all actors whose source shape ids are within selected ids.
389 vtkSmartPointer<vtkActorCollection> anActors = myRenderer->GetActors();
390 anActors->InitTraversal();
391 vtkSmartPointer<vtkActor> anActor = anActors->GetNextActor();
392 while ( anActor.GetPointer() != NULL )
394 if (anActor->GetPickable() && anActor->GetVisibility())
396 if (anActor->GetMapper())
398 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
399 if (!aShape.IsNull())
401 for (IVtk_ShapeIdList::Iterator anIt (anIds); anIt.More(); anIt.Next())
403 if (aShape->GetId() == anIt.Value())
405 aRes->AddItem (anActor);
411 anActor = anActors->GetNextActor();