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 |
40 | vtkStandardNewMacro(IVtkTools_ShapePicker) |
913a4c4a |
41 | |
42 | //============================================================================ |
43 | // Method: IVtkTools_ShapePicker |
44 | // Purpose: Constructs the picker with empty renderer and ready for point selection. |
45 | //============================================================================ |
46 | IVtkTools_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 | //============================================================================ |
57 | IVtkTools_ShapePicker::~IVtkTools_ShapePicker() |
58 | { |
59 | } |
60 | |
61 | //============================================================================ |
62 | // Method: SetTolerance |
63 | // Purpose: Setter for tolerance of picking. |
64 | //============================================================================ |
65 | void IVtkTools_ShapePicker::SetTolerance (float theTolerance ) |
66 | { |
67 | myTolerance = theTolerance; |
68 | } |
69 | |
70 | //============================================================================ |
71 | // Method: GetTolerance |
72 | // Purpose: Getter for tolerance of picking. |
73 | //============================================================================ |
74 | float IVtkTools_ShapePicker::GetTolerance( ) const |
75 | { |
76 | return myTolerance; |
77 | } |
78 | |
79 | //============================================================================ |
80 | // Method: convertDisplayToWorld |
81 | // Purpose: Convert display coordinates to world coordinates |
82 | //============================================================================ |
5ca413ce |
83 | bool 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 | //============================================================================ |
110 | int 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 | //============================================================================ |
122 | int 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 | //============================================================================ |
134 | int 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 | //============================================================================ |
146 | int 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 | //============================================================================ |
177 | void 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 | //============================================================================ |
206 | void 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 | //============================================================================ |
225 | void 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 | //============================================================================ |
234 | IVtk_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 | //============================================================================ |
244 | IVtk_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 | //============================================================================ |
260 | void 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 | //============================================================================ |
271 | void 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 | //============================================================================ |
286 | void 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 | //============================================================================ |
317 | IVtk_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 | //============================================================================ |
337 | void 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 | //============================================================================ |
346 | void 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 | //============================================================================ |
359 | IVtk_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 |
382 | vtkSmartPointer<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 | } |