0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / IVtkTools / IVtkTools_ShapePicker.cxx
CommitLineData
913a4c4a 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>
a9660929 19
20// prevent disabling some MSVC warning messages by VTK headers
21#ifdef _MSC_VER
22#pragma warning(push)
23#endif
913a4c4a 24#include <vtkCommand.h>
25#include <vtkObjectFactory.h>
26#include <vtkRenderer.h>
27#include <vtkActorCollection.h>
a9660929 28#ifdef _MSC_VER
29#pragma warning(pop)
30#endif
913a4c4a 31
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.
39
68858c7d 40vtkStandardNewMacro(IVtkTools_ShapePicker)
913a4c4a 41
42//============================================================================
43// Method: IVtkTools_ShapePicker
44// Purpose: Constructs the picker with empty renderer and ready for point selection.
45//============================================================================
46IVtkTools_ShapePicker::IVtkTools_ShapePicker()
a2f76b15 47: myRenderer (NULL),
913a4c4a 48 myIsRectSelection (false)
49{
50 myOccPickerAlgo = new IVtkOCC_ShapePickerAlgo();
51}
52
53//============================================================================
54// Method: ~IVtkTools_ShapePicker
55// Purpose: Destructor
56//============================================================================
57IVtkTools_ShapePicker::~IVtkTools_ShapePicker()
58{
59}
60
61//============================================================================
62// Method: SetTolerance
63// Purpose: Setter for tolerance of picking.
64//============================================================================
65void IVtkTools_ShapePicker::SetTolerance (float theTolerance )
66{
67 myTolerance = theTolerance;
68}
69
70//============================================================================
71// Method: GetTolerance
72// Purpose: Getter for tolerance of picking.
73//============================================================================
74float IVtkTools_ShapePicker::GetTolerance( ) const
75{
76 return myTolerance;
77}
78
79//============================================================================
80// Method: convertDisplayToWorld
81// Purpose: Convert display coordinates to world coordinates
82//============================================================================
5ca413ce 83bool IVtkTools_ShapePicker::convertDisplayToWorld (vtkRenderer *theRenderer,
84 double theDisplayCoord[3],
85 double theWorldCoord[3])
913a4c4a 86{
87 // Convert the selection point into world coordinates.
88 theRenderer->SetDisplayPoint (theDisplayCoord[0], theDisplayCoord[1], theDisplayCoord[2]);
89 theRenderer->DisplayToWorld();
90
a2f76b15 91 double aCoords[4];
92 theRenderer->GetWorldPoint(aCoords);
913a4c4a 93 if (aCoords[3] == 0.0)
94 {
95 return false;
96 }
97
98 for (Standard_Integer anI = 0; anI < 3; anI++)
99 {
100 theWorldCoord[anI] = aCoords[anI] / aCoords[3];
101 }
a2f76b15 102
913a4c4a 103 return true;
104}
105
106//============================================================================
107// Method: Pick
108// Purpose: Pick entities in the given point.
109//============================================================================
110int IVtkTools_ShapePicker::Pick (double theX, double theY, double /*theZ*/, vtkRenderer *theRenderer)
111{
112 double aPos[2] = {theX, theY};
113 myIsRectSelection = false;
114 myIsPolySelection = false;
115 return pick (aPos, theRenderer);
116}
117
118//============================================================================
119// Method: pick
120// Purpose: Pick entities in the given rectangle area.
121//============================================================================
122int IVtkTools_ShapePicker::Pick (double theXPMin, double theYPMin, double theXPMax, double theYPMax,
123 vtkRenderer *theRenderer)
124{
125 double aPos[4] = {theXPMin, theYPMin, theXPMax, theYPMax};
126 myIsRectSelection = true;
127 myIsPolySelection = false;
128 return pick (aPos, theRenderer);
129}
130//============================================================================
131// Method: pick
132// Purpose: Pick entities in the given polygonal area.
133//============================================================================
134int IVtkTools_ShapePicker::Pick (double thePoly[][3], const int theNbPoints,
135 vtkRenderer *theRenderer)
136{
137 myIsRectSelection = false;
138 myIsPolySelection = true;
139 return pick ((double*)thePoly, theRenderer, theNbPoints);
140}
141
142//============================================================================
143// Method: pick
144// Purpose: Pick entities in the given point or area.
145//============================================================================
146int IVtkTools_ShapePicker::pick (double* thePos,
147 vtkRenderer *theRenderer,
148 const int theNbPoints)
149{
150 // Initialize picking process
151 Initialize();
152
153 // Emit StartPickEvent for observer callbacks (if any)
154 InvokeEvent(vtkCommand::StartPickEvent, NULL);
155
a2f76b15 156 vtkSmartPointer<vtkRenderer> aRenderer;
913a4c4a 157 if (theRenderer == NULL)
158 {
159 aRenderer = myRenderer; // by default use own renderer
160 }
161 else
162 {
163 aRenderer = theRenderer;
164 }
165 doPickImpl (thePos, aRenderer, theNbPoints);
166
167 // Emit EndPickEvent for observer callbacks (if any)
168 InvokeEvent(vtkCommand::EndPickEvent, NULL);
169
170 return myOccPickerAlgo->NbPicked();
171}
172
173//============================================================================
174// Method: doPickImpl
175// Purpose: Implementation of picking algorithm.
176//============================================================================
177void IVtkTools_ShapePicker::doPickImpl (double* thePos,
178 vtkRenderer* theRenderer,
179 const int theNbPoints)
180{
181 // Make sure the correct renderer is used
182 SetRenderer (theRenderer);
183
184 if (myIsPolySelection)
185 {
186 myOccPickerAlgo->Pick ((double**)thePos, theNbPoints);
187 }
188 else if (myIsRectSelection)
189 {
190 myOccPickerAlgo->Pick (thePos[0], thePos[1], thePos[2], thePos[3]);
191 }
192 else
193 {
194 myOccPickerAlgo->Pick (thePos[0], thePos[1]);
195 }
1e756cb9 196
197 PickPosition[0] = myOccPickerAlgo->TopPickedPoint().X();
198 PickPosition[1] = myOccPickerAlgo->TopPickedPoint().Y();
199 PickPosition[2] = myOccPickerAlgo->TopPickedPoint().Z();
913a4c4a 200}
201
202//============================================================================
203// Method: SetRenderer
204// Purpose: Sets the renderer to be used by OCCT selection algorithm
205//============================================================================
206void IVtkTools_ShapePicker::SetRenderer (vtkRenderer* theRenderer)
207{
a2f76b15 208 if (theRenderer == myRenderer.GetPointer())
913a4c4a 209 {
210 return;
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();
214 }
215
216 myRenderer = theRenderer;
217 IVtkVTK_View::Handle aView = new IVtkVTK_View (myRenderer);
218 myOccPickerAlgo->SetView (aView);
219}
220
221//============================================================================
222// Method: SetAreaSelection
223// Purpose: Sets area selection on/off
224//============================================================================
225void IVtkTools_ShapePicker::SetAreaSelection (bool theIsOn)
226{
227 myIsRectSelection = theIsOn;
228}
229
230//============================================================================
231// Method: GetSelectionModes
232// Purpose: Get activated selection modes for a shape.
233//============================================================================
234IVtk_SelectionModeList IVtkTools_ShapePicker::GetSelectionModes (
235 const IVtk_IShape::Handle& theShape) const
236{
237 return myOccPickerAlgo->GetSelectionModes (theShape);
238}
239
240//============================================================================
241// Method: GetSelectionModes
242// Purpose: Get activated selection modes for a shape actor.
243//============================================================================
244IVtk_SelectionModeList IVtkTools_ShapePicker::GetSelectionModes (
245 vtkActor* theShapeActor) const
246{
247 IVtk_SelectionModeList aRes;
248 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
249 if (!aShape.IsNull())
250 {
251 aRes = myOccPickerAlgo->GetSelectionModes (aShape);
252 }
253 return aRes;
254}
255
256//============================================================================
257// Method: SetSelectionMode
258// Purpose: Turn on/off a selection mode for a shape.
259//============================================================================
260void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_IShape::Handle& theShape,
261 const IVtk_SelectionMode theMode,
262 const bool theIsTurnOn) const
263{
264 myOccPickerAlgo->SetSelectionMode (theShape, theMode, theIsTurnOn);
265}
266
267//============================================================================
268// Method: SetSelectionMode
269// Purpose: Turn on/off a selection mode for a shape actor.
270//============================================================================
271void IVtkTools_ShapePicker::SetSelectionMode (vtkActor* theShapeActor,
272 const IVtk_SelectionMode theMode,
273 const bool theIsTurnOn) const
274{
275 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (theShapeActor);
276 if (!aShape.IsNull())
277 {
278 myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
279 }
280}
281
282//============================================================================
283// Method: SetSelectionMode
284// Purpose: Sets the current selection mode for all visible shape objects.
285//============================================================================
286void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_SelectionMode theMode,
287 const bool theIsTurnOn) const
288{
a2f76b15 289 if (myRenderer.GetPointer() != NULL)
913a4c4a 290 {
291 // Obtain all OccShapes displayed and activate the specified selection mode
a2f76b15 292 vtkSmartPointer<vtkActorCollection> anActors = myRenderer->GetActors();
913a4c4a 293 anActors->InitTraversal();
a2f76b15 294 vtkSmartPointer<vtkActor> anActor = anActors->GetNextActor();
295 while ( anActor.GetPointer() != NULL )
913a4c4a 296 {
297 if (anActor->GetPickable() && anActor->GetVisibility())
298 {
299 if (anActor->GetMapper())
300 {
301 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
302 if (!aShape.IsNull())
303 {
304 myOccPickerAlgo->SetSelectionMode (aShape, theMode, theIsTurnOn);
305 }
306 }
307 }
a2f76b15 308 anActor = anActors->GetNextActor();
913a4c4a 309 }
310 }
311}
312
313//============================================================================
314// Method: GetPickedShapesIds
315// Purpose: Access to the list of top-level shapes picked.
316//============================================================================
317IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedShapesIds (bool theIsAll) const
318{
319 if (theIsAll || myIsRectSelection )
320 {
321 return myOccPickerAlgo->ShapesPicked();
322 }
323
324 IVtk_ShapeIdList aRes;
325 IVtk_ShapeIdList aPicked = myOccPickerAlgo->ShapesPicked();
326 if (!aPicked.IsEmpty())
327 {
328 aRes.Append (aPicked.First());
329 }
330 return aRes;
331}
332
a2f76b15 333//============================================================================
334// Method: RemoveSelectableActor
335// Purpose: Remove selectable object from the picker (from internal maps).
336//============================================================================
337void IVtkTools_ShapePicker::RemoveSelectableObject(const IVtk_IShape::Handle& theShape)
338{
339 myOccPickerAlgo->RemoveSelectableObject(theShape);
340}
341
342//============================================================================
343// Method: RemoveSelectableActor
344// Purpose: Remove selectable object from the picker (from internal maps).
345//============================================================================
346void IVtkTools_ShapePicker::RemoveSelectableActor(vtkActor* theShapeActor)
347{
348 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape(theShapeActor);
349 if (!aShape.IsNull())
350 {
351 RemoveSelectableObject(aShape);
352 }
353}
354
913a4c4a 355//============================================================================
356// Method: GetPickedSubShapesIds
357// Purpose: Access to the list of sub-shapes ids picked.
358//============================================================================
359IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedSubShapesIds (const IVtk_IdType theId, bool theIsAll) const
360{
361 IVtk_ShapeIdList aRes;
362 if (theIsAll)
363 {
a2f76b15 364 myOccPickerAlgo->SubShapesPicked (theId, aRes);
913a4c4a 365 }
366 else
367 {
368 IVtk_ShapeIdList aList;
369 myOccPickerAlgo->SubShapesPicked (theId, aList);
370 if (!aList.IsEmpty())
371 {
372 aRes.Append (aList.First());
373 }
374 }
375 return aRes;
376}
377
378//============================================================================
379// Method: GetPickedActors
380// Purpose: Access to the list of actors picked.
381//============================================================================
a2f76b15 382vtkSmartPointer<vtkActorCollection> IVtkTools_ShapePicker::GetPickedActors (bool theIsAll) const
913a4c4a 383{
a2f76b15 384 vtkSmartPointer<vtkActorCollection> aRes = vtkSmartPointer<vtkActorCollection>::New();
913a4c4a 385 IVtk_ShapeIdList anIds = GetPickedShapesIds (theIsAll);
a2f76b15 386 if (myRenderer.GetPointer() != NULL)
913a4c4a 387 {
388 // Obtain all actors whose source shape ids are within selected ids.
a2f76b15 389 vtkSmartPointer<vtkActorCollection> anActors = myRenderer->GetActors();
913a4c4a 390 anActors->InitTraversal();
a2f76b15 391 vtkSmartPointer<vtkActor> anActor = anActors->GetNextActor();
392 while ( anActor.GetPointer() != NULL )
913a4c4a 393 {
394 if (anActor->GetPickable() && anActor->GetVisibility())
395 {
396 if (anActor->GetMapper())
397 {
398 IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape (anActor);
399 if (!aShape.IsNull())
400 {
401 for (IVtk_ShapeIdList::Iterator anIt (anIds); anIt.More(); anIt.Next())
402 {
403 if (aShape->GetId() == anIt.Value())
404 {
405 aRes->AddItem (anActor);
406 }
407 }
408 }
409 }
410 }
a2f76b15 411 anActor = anActors->GetNextActor();
913a4c4a 412 }
413 }
414 return aRes;
415}