Salome HOME
#1189 Tab - Cancel - Enter validate not cancel: In case of disabled Apply button...
[modules/shaper.git] / src / XGUI / XGUI_Selection.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        XGUI_Selection.cpp
4 // Created:     8 July 2014
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "XGUI_Selection.h"
8 #include "XGUI_Workshop.h"
9 #include "XGUI_Displayer.h"
10 #include "XGUI_ViewerProxy.h"
11 #include "XGUI_ObjectsBrowser.h"
12
13 #include "ModuleBase_ResultPrs.h"
14
15 #include <ModelAPI_Feature.h>
16 #include <ModelAPI_Tools.h>
17
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_Axis.hxx>
20 #include <AIS_Point.hxx>
21 #include <Geom_Line.hxx>
22 #include <BRep_Builder.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <Geom_Point.hxx>
25 #include <Geom_TrimmedCurve.hxx>
26 #include <Prs3d_DatumAspect.hxx>
27
28 #include <TColStd_ListIteratorOfListOfInteger.hxx>
29 #include <StdSelect_BRepOwner.hxx>
30
31 #include <set>
32
33 #define DEBUG_DELIVERY
34
35 XGUI_Selection::XGUI_Selection(XGUI_Workshop* theWorkshop)
36     : myWorkshop(theWorkshop)
37 {
38 }
39
40 QList<ModuleBase_ViewerPrs> XGUI_Selection::getSelected(const SelectionPlace& thePlace) const
41 {
42   QList<ModuleBase_ViewerPrs> aPresentations;
43
44   switch (thePlace) {
45     case Browser:
46       getSelectedInBrowser(aPresentations);
47     break;
48     case Viewer:
49       getSelectedInViewer(aPresentations);
50     break;
51   case AllControls:
52       getSelectedInViewer(aPresentations);
53       getSelectedInBrowser(aPresentations);
54     break;
55   }
56   return aPresentations;
57 }
58
59 Handle(AIS_InteractiveObject) XGUI_Selection::getIO(const ModuleBase_ViewerPrs& thePrs)
60 {
61   Handle(AIS_InteractiveObject) anIO = thePrs.interactive();
62   if (anIO.IsNull()) {
63     Handle(SelectMgr_EntityOwner) anOwner = thePrs.owner();
64     if (!anOwner.IsNull())
65       anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
66
67     if (anIO.IsNull() && thePrs.object()) {
68       XGUI_Displayer* aDisplayer = myWorkshop->displayer();
69       AISObjectPtr anAISObject = aDisplayer->getAISObject(thePrs.object());
70       if (anAISObject.get())
71         anIO = anAISObject->impl<Handle(AIS_InteractiveObject)>();
72     }
73   }
74   return anIO;
75 }
76
77 void XGUI_Selection::getSelectedInViewer(QList<ModuleBase_ViewerPrs>& thePresentations) const
78 {
79   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
80   if (!aContext.IsNull() && aContext->HasOpenedContext()) {
81     QList<long> aSelectedIds; // Remember of selected address in order to avoid duplicates
82     for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
83       ModuleBase_ViewerPrs aPrs;
84       Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
85
86       if (aSelectedIds.contains((long)anOwner.Access()))
87         continue;
88       aSelectedIds.append((long)anOwner.Access());
89
90       fillPresentation(aPrs, anOwner);
91
92       if (!thePresentations.contains(aPrs)) // TODO: check whether the presentation in a list
93         thePresentations.append(aPrs);
94     }
95   }
96 }
97
98 void XGUI_Selection::getSelectedInBrowser(QList<ModuleBase_ViewerPrs>& thePresentations) const
99 {
100   // collect the objects  of the parameter presentation to avoid a repeted objects in the result
101   QObjectPtrList aPresentationObjects;
102   QList<ModuleBase_ViewerPrs>::const_iterator aPrsIt = thePresentations.begin(),
103                                               aPrsLast = thePresentations.end();
104   for (; aPrsIt != aPrsLast; aPrsIt++) {
105     aPresentationObjects.push_back((*aPrsIt).object());
106   }
107
108   QObjectPtrList anObjects = selectedObjects();
109   QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end();
110   for (; anIt != aLast; anIt++) {
111     ObjectPtr anObject = *anIt;
112     if (anObject.get() != NULL && !aPresentationObjects.contains(anObject)) {
113       thePresentations.append(ModuleBase_ViewerPrs(anObject, TopoDS_Shape(), NULL));
114     }
115   }
116 }
117
118 void XGUI_Selection::fillPresentation(ModuleBase_ViewerPrs& thePrs,
119                                       const Handle(SelectMgr_EntityOwner)& theOwner) const
120 {
121   thePrs.setOwner(theOwner);
122
123   Handle(AIS_InteractiveObject) anIO = 
124                            Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable());
125   thePrs.setInteractive(anIO);
126
127   // we should not check the appearance of this feature because there can be some selected shapes
128   // for one feature
129   Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(theOwner);
130   if( !aBRO.IsNull() && aBRO->HasShape() ) {
131     // the located method is called in the context to obtain the shape by the SelectedShape() method,
132     // so the shape is located by the same rules
133     TopoDS_Shape aShape = aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
134 #ifndef DEBUG_DELIVERY
135     if (aShape.IsNull())
136       aShape = findAxisShape(anIO);
137 #endif
138     if (!aShape.IsNull())
139       thePrs.setShape(aShape);
140   } else {
141 #ifdef DEBUG_DELIVERY
142     // Fill by trihedron shapes
143     Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(anIO);
144     if (!aAxis.IsNull()) {
145       // an Axis from Trihedron
146       Handle(Geom_Line) aLine = aAxis->Component();
147       Handle(Prs3d_DatumAspect) DA = aAxis->Attributes()->DatumAspect();
148       Handle(Geom_TrimmedCurve) aTLine = new Geom_TrimmedCurve(aLine, 0, DA->FirstAxisLength());
149
150       BRep_Builder aBuilder;      
151       TopoDS_Edge aEdge;
152       aBuilder.MakeEdge(aEdge, aTLine, Precision::Confusion());
153       if (!aEdge.IsNull())
154         thePrs.setShape(aEdge);
155     } else {
156       Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(anIO);
157       if (!aPoint.IsNull()) {
158         // A point from trihedron
159         Handle(Geom_Point) aPnt = aPoint->Component();
160         BRep_Builder aBuilder;
161         TopoDS_Vertex aVertex;
162         aBuilder.MakeVertex(aVertex, aPnt->Pnt(), Precision::Confusion());
163         if (!aVertex.IsNull())
164           thePrs.setShape(aVertex);
165       }
166     }
167 #endif
168   }
169      
170   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
171   ObjectPtr aFeature = aDisplayer->getObject(anIO);
172
173   Handle(ModuleBase_BRepOwner) aCompSolidBRO = Handle(ModuleBase_BRepOwner)::DownCast(theOwner);
174   if (!aCompSolidBRO.IsNull()) {
175     // If ModuleBase_BRepOwner object is created then it means that TopAbs_COMPSOLID selection mode
176     // is On and we have to use parent result which corresponds to the CompSolid shape
177     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aFeature);
178     if (aResult.get()) {
179       ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(aResult);
180       if (aCompSolid.get()) {
181         GeomShapePtr aShapePtr = aCompSolid->shape();
182         if (aShapePtr.get()) {
183           TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
184           if (aShape.IsEqual(thePrs.shape())) {
185             thePrs.setObject(aCompSolid);
186             return;
187           }
188         }
189       }
190     }
191   }
192   thePrs.setObject(aFeature);
193 }
194
195 QList<ModuleBase_ViewerPrs> XGUI_Selection::getHighlighted() const
196 {
197   QList<ModuleBase_ViewerPrs> aPresentations;
198   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
199   if (aContext.IsNull())
200     return aPresentations;
201
202   QList<long> aSelectedIds; // Remember of selected address in order to avoid duplicates
203   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
204   for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) {
205     ModuleBase_ViewerPrs aPrs;
206     Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive();
207     if (aSelectedIds.contains((long)anIO.Access()))
208       continue;
209     
210     aSelectedIds.append((long)anIO.Access());
211     aPrs.setInteractive(anIO);
212
213     ObjectPtr aResult = aDisplayer->getObject(anIO);
214     // we should not check the appearance of this feature because there can be some selected shapes
215     // for one feature
216     aPrs.setObject(aResult);
217     if (aContext->HasOpenedContext()) {
218       TopoDS_Shape aShape = aContext->DetectedShape();
219       if (!aShape.IsNull())
220         aPrs.setShape(aShape);
221     }
222     aPresentations.push_back(aPrs);
223   }
224   return aPresentations;
225 }
226
227 QObjectPtrList XGUI_Selection::selectedObjects() const
228 {
229   return myWorkshop->objectBrowser()->selectedObjects();
230 }
231
232 void XGUI_Selection::setSelectedObjects( const QObjectPtrList& theObjects ) const
233 {
234   return myWorkshop->objectBrowser()->setObjectsSelected( theObjects );
235 }
236
237 QObjectPtrList XGUI_Selection::selectedPresentations() const
238 {
239   QObjectPtrList aSelectedList;
240
241   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
242   if (!aContext.IsNull()) {
243     for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
244       Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
245       ObjectPtr aResult = myWorkshop->displayer()->getObject(anIO);
246       if (aResult)
247         aSelectedList.append(aResult);
248     }
249   }
250   return aSelectedList;
251 }
252
253 //**************************************************************
254 QModelIndexList XGUI_Selection::selectedIndexes() const
255 {
256   return myWorkshop->objectBrowser()->selectedIndexes();
257 }
258
259 //**************************************************************
260 void XGUI_Selection::selectedAISObjects(AIS_ListOfInteractive& theList) const
261 {
262   theList.Clear();
263
264   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
265   if (!aContext.IsNull()) {
266     for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
267       theList.Append(aContext->SelectedInteractive());
268   }
269 }
270
271 //**************************************************************
272 ObjectPtr XGUI_Selection::getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const
273 {
274   ObjectPtr anObject;
275
276   Handle(SelectMgr_EntityOwner) aEO = theOwner;
277   if (!aEO.IsNull()) {
278     Handle(AIS_InteractiveObject) anObj = 
279       Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable());
280     anObject = myWorkshop->displayer()->getObject(anObj);
281   }
282   return anObject;
283 }
284
285 //**************************************************************
286 void XGUI_Selection::selectedShapes(NCollection_List<TopoDS_Shape>& theList, 
287                                     std::list<ObjectPtr>& theOwners) const
288 {
289   theList.Clear();
290   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
291   if (aContext.IsNull())
292     return;
293
294   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
295     TopoDS_Shape aShape = aContext->SelectedShape();
296     if (aShape.IsNull()) {
297       aShape = findAxisShape(aContext->SelectedInteractive());
298     }
299     if (!aShape.IsNull()) {
300       theList.Append(aShape);
301       Handle(SelectMgr_EntityOwner) aEO = aContext->SelectedOwner();
302       if (!aEO.IsNull()) {
303         Handle(AIS_InteractiveObject) anObj = 
304           Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable());
305         ObjectPtr anObject = myWorkshop->displayer()->getObject(anObj);
306         theOwners.push_back(anObject);
307       }
308     }
309   }
310 }
311
312 //**************************************************************
313 void XGUI_Selection::selectedOwners(SelectMgr_IndexedMapOfOwner& theSelectedOwners) const
314 {
315   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
316   if (!aContext.IsNull()) {
317     for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
318       theSelectedOwners.Add(aContext->SelectedOwner());
319     }
320   }
321 }
322
323 //**************************************************************
324 void XGUI_Selection::entityOwners(const Handle(AIS_InteractiveObject)& theObject,
325                                   SelectMgr_IndexedMapOfOwner& theOwners) const
326 {
327   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
328   if (aContext.IsNull() || theObject.IsNull())
329     return;
330
331   TColStd_ListOfInteger aModes;
332   aContext->ActivatedModes(theObject, aModes);
333
334   TColStd_ListIteratorOfListOfInteger anIt(aModes);
335   for (; anIt.More(); anIt.Next()) {
336     int aMode = anIt.Value();
337     if (!theObject->HasSelection(aMode))
338       continue;
339
340     Handle(SelectMgr_Selection) aSelection = theObject->Selection(aMode);
341     for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
342       Handle(SelectMgr_SensitiveEntity) anEntity = aSelection->Sensitive();
343       if (anEntity.IsNull())
344         continue;
345       Handle(SelectMgr_EntityOwner) anOwner =
346         Handle(SelectMgr_EntityOwner)::DownCast(anEntity->BaseSensitive()->OwnerId());
347       if (!anOwner.IsNull())
348         theOwners.Add(anOwner);
349     }
350   }
351 }
352
353 //**************************************************************
354 TopoDS_Shape XGUI_Selection::findAxisShape(Handle(AIS_InteractiveObject) theIO) const
355 {
356   TopoDS_Shape aShape;
357   // Fill by trihedron shapes
358   Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(theIO);
359   if (!aAxis.IsNull()) {
360     // an Axis from Trihedron
361     Handle(Geom_Line) aLine = aAxis->Component();
362     Handle(Prs3d_DatumAspect) DA = aAxis->Attributes()->DatumAspect();
363     Handle(Geom_TrimmedCurve) aTLine = new Geom_TrimmedCurve(aLine, 0, DA->FirstAxisLength());
364
365     BRep_Builder aBuilder;      
366     TopoDS_Edge aEdge;
367     aBuilder.MakeEdge(aEdge, aTLine, Precision::Confusion());
368     if (!aEdge.IsNull())
369       aShape = aEdge;
370   } else {
371     Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(theIO);
372     if (!aPoint.IsNull()) {
373       // A point from trihedron
374       Handle(Geom_Point) aPnt = aPoint->Component();
375       BRep_Builder aBuilder;
376       TopoDS_Vertex aVertex;
377       aBuilder.MakeVertex(aVertex, aPnt->Pnt(), Precision::Confusion());
378       if (!aVertex.IsNull())
379         aShape = aVertex;
380     }
381   }
382   return aShape;
383 }