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 // Handle implementation
27 //================================================================
28 // Function : Constructor
30 //================================================================
31 IVtkOCC_ShapePickerAlgo::IVtkOCC_ShapePickerAlgo() :
32 myViewerSelector (new IVtkOCC_ViewerSelector())
35 //================================================================
36 // Function : Destructor
38 //================================================================
39 IVtkOCC_ShapePickerAlgo::~IVtkOCC_ShapePickerAlgo()
42 //================================================================
45 //================================================================
46 void IVtkOCC_ShapePickerAlgo::SetView (const IVtk_IView::Handle& theView)
51 //================================================================
52 // Function : GetSelectionModes
54 //================================================================
55 IVtk_SelectionModeList IVtkOCC_ShapePickerAlgo::GetSelectionModes (
56 const IVtk_IShape::Handle& theShape) const
58 IVtk_SelectionModeList aRes;
62 // Get shape implementation from shape interface.
63 Handle(IVtkOCC_Shape) aShapeImpl = Handle(IVtkOCC_Shape)::DownCast(theShape);
65 // Get selectable object from the shape implementation.
66 Handle(IVtkOCC_SelectableObject) aSelObj =
67 Handle(IVtkOCC_SelectableObject)::DownCast(aShapeImpl->GetSelectableObject());
69 if (!aSelObj.IsNull())
71 IVtk_SelectionMode aSelMode;
72 for (aSelMode = SM_Shape; aSelMode <= SM_Compound; aSelMode = (IVtk_SelectionMode)(aSelMode + 1))
74 if (myViewerSelector->IsActive (aSelObj, aSelMode))
76 aRes.Append (aSelMode);
85 //================================================================
86 // Function : SetSelectionMode
88 //================================================================
89 void IVtkOCC_ShapePickerAlgo::SetSelectionMode (const IVtk_IShape::Handle& theShape,
90 const IVtk_SelectionMode theMode,
91 const bool theIsTurnOn)
98 // TODO: treatment for mode == -1 - deactivate the shape...
99 // Is this really needed? The picker and all selection classes
100 // are destroyed when shapes are deactivated...
102 // Get shape implementation from shape interface.
103 Handle(IVtkOCC_Shape) aShapeImpl =
104 Handle(IVtkOCC_Shape)::DownCast(theShape);
106 // Get selectable object from the shape implementation.
107 Handle(IVtkOCC_SelectableObject) aSelObj =
108 Handle(IVtkOCC_SelectableObject)::DownCast(aShapeImpl->GetSelectableObject());
112 // If there is no selectable object then create a new one for this shape.
113 if (aSelObj.IsNull())
115 aSelObj = new IVtkOCC_SelectableObject (aShapeImpl);
118 // If the selectable object has no selection in the given mode
119 if (!aSelObj->HasSelection (theMode))
121 // then create a new selection in the given mode for this object (shape).
122 Handle(SelectMgr_Selection) aNewSelection = new SelectMgr_Selection (theMode);
123 aSelObj->AddSelection (aNewSelection, theMode);
124 myViewerSelector->AddSelectionToObject (aSelObj, aNewSelection);
127 // Update the selection for the given mode according to its status.
128 const Handle(SelectMgr_Selection)& aSel = aSelObj->Selection (theMode);
130 switch (aSel->UpdateStatus())
132 case SelectMgr_TOU_Full:
133 // Recompute the sensitive primitives which correspond to the mode.
134 myViewerSelector->RemoveSelectionOfObject (aSelObj, aSelObj->Selection (theMode));
135 aSelObj->RecomputePrimitives (theMode);
136 myViewerSelector->AddSelectionToObject (aSelObj, aSelObj->Selection (theMode));
137 myViewerSelector->RebuildObjectsTree();
138 myViewerSelector->RebuildSensitivesTree (aSelObj);
139 case SelectMgr_TOU_Partial:
141 if (aSelObj->HasTransformation())
143 myViewerSelector->RebuildObjectsTree();
150 // Set status of the selection to "nothing to update".
151 aSel->UpdateStatus (SelectMgr_TOU_None);
153 // Activate the selection in the viewer selector.
154 myViewerSelector->Activate (aSelObj->Selection (theMode));
158 { // turn off the selection mode
160 if (!aSelObj.IsNull())
162 if (aSelObj->HasSelection (theMode))
164 const Handle(SelectMgr_Selection)& aSel = aSelObj->Selection (theMode);
165 myViewerSelector->Deactivate (aSel);
171 //================================================================
172 // Function : SetSelectionMode
174 //================================================================
175 void IVtkOCC_ShapePickerAlgo::SetSelectionMode (const IVtk_ShapePtrList& theShapes,
176 const IVtk_SelectionMode theMode,
177 const bool /*theIsTurnOn*/)
179 IVtk_IShape::Handle aShape;
180 IVtk_ShapePtrList::Iterator anIt (theShapes);
181 for (; anIt.More(); anIt.Next())
183 aShape = anIt.Value();
184 SetSelectionMode (aShape, theMode);
188 //================================================================
191 //================================================================
192 bool IVtkOCC_ShapePickerAlgo::Pick (const double theX, const double theY)
196 // Calling OCCT algortihm
197 myViewerSelector->Pick ((Standard_Integer)theX,
198 (Standard_Integer)theY,
202 return processPicked();
205 //================================================================
208 //================================================================
209 bool IVtkOCC_ShapePickerAlgo::Pick (const double theXMin,
210 const double theYMin,
211 const double theXMax,
212 const double theYMax)
216 // Calling OCCT algortihm
217 myViewerSelector->Pick ((Standard_Integer)theXMin,
218 (Standard_Integer)theYMin,
219 (Standard_Integer)theXMax,
220 (Standard_Integer)theYMax,
224 return processPicked();
227 //================================================================
230 //================================================================
231 bool IVtkOCC_ShapePickerAlgo::Pick (double** thePoly,
232 const int theNbPoints)
236 // Calling OCCT algortihm
237 myViewerSelector->Pick (thePoly, theNbPoints, myView);
240 return processPicked();
243 //================================================================
244 // Function : ShapesPicked
246 //================================================================
247 const IVtk_ShapeIdList& IVtkOCC_ShapePickerAlgo::ShapesPicked() const
249 return myShapesPicked;
252 //================================================================
253 // Function : SubShapesPicked
255 //================================================================
256 void IVtkOCC_ShapePickerAlgo::SubShapesPicked (const IVtk_IdType theId, IVtk_ShapeIdList& theShapeList) const
258 if (mySubShapesPicked.IsBound (theId))
260 // Need non-const this to call the map's operator[]
261 IVtkOCC_ShapePickerAlgo* that = const_cast< IVtkOCC_ShapePickerAlgo* >(this);
262 theShapeList = that->mySubShapesPicked (theId);
266 //================================================================
267 // Function : clearPicked
268 // Purpose : Internal method, resets picked data
269 //================================================================
270 void IVtkOCC_ShapePickerAlgo::clearPicked()
272 myShapesPicked.Clear();
273 mySubShapesPicked.Clear();
276 //================================================================
277 // Function : NbPicked
278 // Purpose : Get number of picked entities.
279 //================================================================
280 int IVtkOCC_ShapePickerAlgo::NbPicked()
282 return myShapesPicked.Extent();
285 //================================================================
286 // Function : processPicked
288 //================================================================
289 bool IVtkOCC_ShapePickerAlgo::processPicked()
291 Standard_Integer aNbPicked = myViewerSelector->NbPicked();
292 Handle(StdSelect_BRepOwner) anEntityOwner;
293 Handle(Message_Messenger) anOutput = Message::DefaultMessenger();
295 for (Standard_Integer aDetectIt = 1; aDetectIt <= aNbPicked; aDetectIt++)
297 // ViewerSelector detects sensitive entities under the mouse
298 // and for each entity returns its entity owner.
299 // StdSelect_BRepOwner instance holds corresponding sub-shape (TopoDS_Shape)
300 // and in general entity owners have a pointer to SelectableObject that can tell us
301 // what is the top-level TopoDS_Shape.
302 anEntityOwner = Handle(StdSelect_BRepOwner)::DownCast (myViewerSelector->Picked (aDetectIt));
303 if (!anEntityOwner.IsNull())
305 Handle(IVtkOCC_SelectableObject) aSelectable =
306 Handle(IVtkOCC_SelectableObject)::DownCast (anEntityOwner->Selectable());
310 anOutput << "Error: EntityOwner having null SelectableObject picked!";
314 Handle(IVtkOCC_Shape) aSelShape = aSelectable->GetShape();
317 anOutput << "Error: SelectableObject with null OccShape pointer picked!";
321 IVtk_IdType aTopLevelId = aSelShape->GetId();
322 myShapesPicked.Append (aTopLevelId);
324 // Now try to guess if it's the top-level shape itself or just a sub-shape picked
325 TopoDS_Shape aTopLevelShape = aSelShape->GetShape();
326 TopoDS_Shape aSubShape = anEntityOwner->Shape();
327 if (aTopLevelShape.IsNull())
329 anOutput << "Error: OccShape with null top-level TopoDS_Shape picked!";
332 if (aSubShape.IsNull())
334 anOutput << "Error: EntityOwner with null TopoDS_Shape picked!";
338 if (!aSubShape.IsSame (aTopLevelShape))
340 IVtk_IdType aSubId = aSelShape->GetSubShapeId (aSubShape);
342 if (!mySubShapesPicked.IsBound (aTopLevelId))
344 const IVtk_ShapeIdList aList;
345 mySubShapesPicked.Bind (aTopLevelId, aList);
347 // Order of selected sub-shapes
348 mySubShapesPicked (aTopLevelId).Append (aSubId);
353 return !myShapesPicked.IsEmpty();