1 // Created on: 2011-10-14
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 <IVtk_Types.hxx>
17 #include <IVtkOCC_ShapePickerAlgo.hxx>
18 #include <IVtkOCC_Shape.hxx>
19 #include <IVtkOCC_SelectableObject.hxx>
20 #include <Message.hxx>
21 #include <Message_Messenger.hxx>
22 #include <StdSelect_BRepOwner.hxx>
24 IMPLEMENT_STANDARD_RTTIEXT(IVtkOCC_ShapePickerAlgo,IVtk_IShapePickerAlgo)
26 // Handle implementation
29 //================================================================
30 // Function : Constructor
32 //================================================================
33 IVtkOCC_ShapePickerAlgo::IVtkOCC_ShapePickerAlgo() :
34 myViewerSelector (new IVtkOCC_ViewerSelector())
37 //================================================================
38 // Function : Destructor
40 //================================================================
41 IVtkOCC_ShapePickerAlgo::~IVtkOCC_ShapePickerAlgo()
44 //================================================================
47 //================================================================
48 void IVtkOCC_ShapePickerAlgo::SetView (const IVtk_IView::Handle& theView)
53 //================================================================
54 // Function : GetSelectionModes
56 //================================================================
57 IVtk_SelectionModeList IVtkOCC_ShapePickerAlgo::GetSelectionModes (
58 const IVtk_IShape::Handle& theShape) const
60 IVtk_SelectionModeList aRes;
62 if (! theShape.IsNull())
64 // Get shape implementation from shape interface.
65 Handle(IVtkOCC_Shape) aShapeImpl = Handle(IVtkOCC_Shape)::DownCast(theShape);
67 // Get selectable object from the shape implementation.
68 Handle(IVtkOCC_SelectableObject) aSelObj =
69 Handle(IVtkOCC_SelectableObject)::DownCast(aShapeImpl->GetSelectableObject());
71 if (!aSelObj.IsNull())
73 IVtk_SelectionMode aSelMode;
74 for (aSelMode = SM_Shape; aSelMode <= SM_Compound; aSelMode = (IVtk_SelectionMode)(aSelMode + 1))
76 if (myViewerSelector->IsActive (aSelObj, aSelMode))
78 aRes.Append (aSelMode);
87 //================================================================
88 // Function : SetSelectionMode
90 //================================================================
91 void IVtkOCC_ShapePickerAlgo::SetSelectionMode (const IVtk_IShape::Handle& theShape,
92 const IVtk_SelectionMode theMode,
93 const bool theIsTurnOn)
95 if (theShape.IsNull())
100 // TODO: treatment for mode == -1 - deactivate the shape...
101 // Is this really needed? The picker and all selection classes
102 // are destroyed when shapes are deactivated...
104 // Get shape implementation from shape interface.
105 Handle(IVtkOCC_Shape) aShapeImpl =
106 Handle(IVtkOCC_Shape)::DownCast(theShape);
108 // Get selectable object from the shape implementation.
109 Handle(IVtkOCC_SelectableObject) aSelObj =
110 Handle(IVtkOCC_SelectableObject)::DownCast(aShapeImpl->GetSelectableObject());
114 // If there is no selectable object then create a new one for this shape.
115 if (aSelObj.IsNull())
117 aSelObj = new IVtkOCC_SelectableObject (aShapeImpl);
120 // If the selectable object has no selection in the given mode
121 if (!aSelObj->HasSelection (theMode))
123 // then create a new selection in the given mode for this object (shape).
124 Handle(SelectMgr_Selection) aNewSelection = new SelectMgr_Selection (theMode);
125 aSelObj->AddSelection (aNewSelection, theMode);
126 myViewerSelector->AddSelectionToObject (aSelObj, aNewSelection);
129 // Update the selection for the given mode according to its status.
130 const Handle(SelectMgr_Selection)& aSel = aSelObj->Selection (theMode);
132 switch (aSel->UpdateStatus())
134 case SelectMgr_TOU_Full:
135 // Recompute the sensitive primitives which correspond to the mode.
136 myViewerSelector->RemoveSelectionOfObject (aSelObj, aSelObj->Selection (theMode));
137 aSelObj->RecomputePrimitives (theMode);
138 myViewerSelector->AddSelectionToObject (aSelObj, aSelObj->Selection (theMode));
139 myViewerSelector->RebuildObjectsTree();
140 myViewerSelector->RebuildSensitivesTree (aSelObj);
141 case SelectMgr_TOU_Partial:
143 if (aSelObj->HasTransformation())
145 myViewerSelector->RebuildObjectsTree();
152 // Set status of the selection to "nothing to update".
153 aSel->UpdateStatus (SelectMgr_TOU_None);
155 // Activate the selection in the viewer selector.
156 myViewerSelector->Activate (aSelObj->Selection (theMode));
160 { // turn off the selection mode
162 if (!aSelObj.IsNull())
164 if (aSelObj->HasSelection (theMode))
166 const Handle(SelectMgr_Selection)& aSel = aSelObj->Selection (theMode);
167 myViewerSelector->Deactivate (aSel);
173 //================================================================
174 // Function : SetSelectionMode
176 //================================================================
177 void IVtkOCC_ShapePickerAlgo::SetSelectionMode (const IVtk_ShapePtrList& theShapes,
178 const IVtk_SelectionMode theMode,
179 const bool /*theIsTurnOn*/)
181 IVtk_IShape::Handle aShape;
182 IVtk_ShapePtrList::Iterator anIt (theShapes);
183 for (; anIt.More(); anIt.Next())
185 aShape = anIt.Value();
186 SetSelectionMode (aShape, theMode);
190 //================================================================
193 //================================================================
194 bool IVtkOCC_ShapePickerAlgo::Pick (const double theX, const double theY)
198 // Calling OCCT algortihm
199 myViewerSelector->Pick ((Standard_Integer)theX,
200 (Standard_Integer)theY,
204 return processPicked();
207 //================================================================
210 //================================================================
211 bool IVtkOCC_ShapePickerAlgo::Pick (const double theXMin,
212 const double theYMin,
213 const double theXMax,
214 const double theYMax)
218 // Calling OCCT algortihm
219 myViewerSelector->Pick ((Standard_Integer)theXMin,
220 (Standard_Integer)theYMin,
221 (Standard_Integer)theXMax,
222 (Standard_Integer)theYMax,
226 return processPicked();
229 //================================================================
232 //================================================================
233 bool IVtkOCC_ShapePickerAlgo::Pick (double** thePoly,
234 const int theNbPoints)
238 // Calling OCCT algortihm
239 myViewerSelector->Pick (thePoly, theNbPoints, myView);
242 return processPicked();
245 //================================================================
246 // Function : ShapesPicked
248 //================================================================
249 const IVtk_ShapeIdList& IVtkOCC_ShapePickerAlgo::ShapesPicked() const
251 return myShapesPicked;
254 //================================================================
255 // Function : SubShapesPicked
257 //================================================================
258 void IVtkOCC_ShapePickerAlgo::SubShapesPicked (const IVtk_IdType theId, IVtk_ShapeIdList& theShapeList) const
260 if (mySubShapesPicked.IsBound (theId))
262 theShapeList = mySubShapesPicked (theId);
266 //================================================================
267 // Function : clearPicked
268 // Purpose : Internal method, resets picked data
269 //================================================================
270 void IVtkOCC_ShapePickerAlgo::clearPicked()
272 myTopPickedPoint.SetCoord (RealLast(), RealLast(), RealLast());
273 myShapesPicked.Clear();
274 mySubShapesPicked.Clear();
277 //================================================================
278 // Function : NbPicked
279 // Purpose : Get number of picked entities.
280 //================================================================
281 int IVtkOCC_ShapePickerAlgo::NbPicked()
283 return myShapesPicked.Extent();
286 //================================================================
287 // Function : processPicked
289 //================================================================
290 bool IVtkOCC_ShapePickerAlgo::processPicked()
292 Standard_Integer aNbPicked = myViewerSelector->NbPicked();
294 Handle(StdSelect_BRepOwner) anEntityOwner;
295 Handle(Message_Messenger) anOutput = Message::DefaultMessenger();
298 for (Standard_Integer aDetectIt = 1; aDetectIt <= aNbPicked; aDetectIt++)
300 // ViewerSelector detects sensitive entities under the mouse
301 // and for each entity returns its entity owner.
302 // StdSelect_BRepOwner instance holds corresponding sub-shape (TopoDS_Shape)
303 // and in general entity owners have a pointer to SelectableObject that can tell us
304 // what is the top-level TopoDS_Shape.
305 anEntityOwner = Handle(StdSelect_BRepOwner)::DownCast (myViewerSelector->Picked (aDetectIt));
306 if (!anEntityOwner.IsNull())
308 Handle(IVtkOCC_SelectableObject) aSelectable =
309 Handle(IVtkOCC_SelectableObject)::DownCast (anEntityOwner->Selectable());
311 if (aSelectable.IsNull())
313 anOutput->SendAlarm() << "Error: EntityOwner having null SelectableObject picked!";
317 Handle(IVtkOCC_Shape) aSelShape = aSelectable->GetShape();
318 if (aSelShape.IsNull())
320 anOutput->SendAlarm() << "Error: SelectableObject with null OccShape pointer picked!";
324 IVtk_IdType aTopLevelId = aSelShape->GetId();
325 myShapesPicked.Append (aTopLevelId);
329 myTopPickedPoint = myViewerSelector->PickedPoint (aDetectIt);
332 // Now try to guess if it's the top-level shape itself or just a sub-shape picked
333 TopoDS_Shape aTopLevelShape = aSelShape->GetShape();
334 TopoDS_Shape aSubShape = anEntityOwner->Shape();
335 if (aTopLevelShape.IsNull())
337 anOutput->SendAlarm() << "Error: OccShape with null top-level TopoDS_Shape picked!";
340 if (aSubShape.IsNull())
342 anOutput->SendAlarm() << "Error: EntityOwner with null TopoDS_Shape picked!";
346 if (!aSubShape.IsSame (aTopLevelShape))
348 IVtk_IdType aSubId = aSelShape->GetSubShapeId (aSubShape);
350 if (!mySubShapesPicked.IsBound (aTopLevelId))
352 const IVtk_ShapeIdList aList;
353 mySubShapesPicked.Bind (aTopLevelId, aList);
355 // Order of selected sub-shapes
356 mySubShapesPicked (aTopLevelId).Append (aSubId);
361 return !myShapesPicked.IsEmpty();
364 //============================================================================
365 // Method: RemoveSelectableActor
366 // Purpose: Remove selectable object from the picker (from internal maps).
367 //============================================================================
368 void IVtkOCC_ShapePickerAlgo::RemoveSelectableObject(const IVtk_IShape::Handle& theShape)
371 // Get shape implementation from shape interface.
372 Handle(IVtkOCC_Shape) aShapeImpl =
373 Handle(IVtkOCC_Shape)::DownCast(theShape);
375 // Get selectable object from the shape implementation.
376 Handle(IVtkOCC_SelectableObject) aSelObj =
377 Handle(IVtkOCC_SelectableObject)::DownCast(aShapeImpl->GetSelectableObject());
379 myViewerSelector->RemoveSelectableObject(aSelObj);
380 myViewerSelector->Clear();
381 aShapeImpl->SetSelectableObject(NULL);