]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_Selection.cpp
Salome HOME
ModuleBase_ViewerPrs is wrapped into shared_ptr.
[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_ViewerPrsPtr> XGUI_Selection::getSelected(const SelectionPlace& thePlace) const
41 {
42   QList<ModuleBase_ViewerPrsPtr> 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_ViewerPrsPtr& 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_ViewerPrsPtr>& 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_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs());
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_ViewerPrsPtr>& 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_ViewerPrsPtr>::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(std::shared_ptr<ModuleBase_ViewerPrs>(
114                new ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL)));
115     }
116   }
117 }
118
119 void XGUI_Selection::fillPresentation(ModuleBase_ViewerPrsPtr& thePrs,
120                                       const Handle(SelectMgr_EntityOwner)& theOwner) const
121 {
122   thePrs->setOwner(theOwner);
123
124   Handle(AIS_InteractiveObject) anIO = 
125                            Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable());
126   thePrs->setInteractive(anIO);
127
128   // we should not check the appearance of this feature because there can be some selected shapes
129   // for one feature
130   Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(theOwner);
131   if( !aBRO.IsNull() && aBRO->HasShape() ) {
132     // the located method is called in the context to obtain the shape by the SelectedShape() method,
133     // so the shape is located by the same rules
134     TopoDS_Shape aShape = aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
135 #ifndef DEBUG_DELIVERY
136     if (aShape.IsNull())
137       aShape = findAxisShape(anIO);
138 #endif
139     if (!aShape.IsNull()) {
140       std::shared_ptr<GeomAPI_Shape> aGeomShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
141       aGeomShape->setImpl(new TopoDS_Shape(aShape));
142       thePrs->setShape(aGeomShape);
143     }
144   } else {
145 #ifdef DEBUG_DELIVERY
146     // Fill by trihedron shapes
147     Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(anIO);
148     if (!aAxis.IsNull()) {
149       // an Axis from Trihedron
150       Handle(Geom_Line) aLine = aAxis->Component();
151       Handle(Prs3d_DatumAspect) DA = aAxis->Attributes()->DatumAspect();
152       Handle(Geom_TrimmedCurve) aTLine = new Geom_TrimmedCurve(aLine, 0, DA->FirstAxisLength());
153
154       BRep_Builder aBuilder;      
155       TopoDS_Edge aEdge;
156       aBuilder.MakeEdge(aEdge, aTLine, Precision::Confusion());
157       if (!aEdge.IsNull()) {
158         std::shared_ptr<GeomAPI_Shape> aGeomShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
159         aGeomShape->setImpl(new TopoDS_Shape(aEdge));
160         thePrs->setShape(aGeomShape);
161       }
162     } else {
163       Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(anIO);
164       if (!aPoint.IsNull()) {
165         // A point from trihedron
166         Handle(Geom_Point) aPnt = aPoint->Component();
167         BRep_Builder aBuilder;
168         TopoDS_Vertex aVertex;
169         aBuilder.MakeVertex(aVertex, aPnt->Pnt(), Precision::Confusion());
170         if (!aVertex.IsNull()) {
171           std::shared_ptr<GeomAPI_Shape> aGeomShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
172           aGeomShape->setImpl(new TopoDS_Shape(aVertex));
173           thePrs->setShape(aGeomShape);
174         }
175       }
176     }
177 #endif
178   }
179      
180   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
181   ObjectPtr aFeature = aDisplayer->getObject(anIO);
182
183   Handle(ModuleBase_BRepOwner) aCompSolidBRO = Handle(ModuleBase_BRepOwner)::DownCast(theOwner);
184   if (!aCompSolidBRO.IsNull()) {
185     // If ModuleBase_BRepOwner object is created then it means that TopAbs_COMPSOLID selection mode
186     // is On and we have to use parent result which corresponds to the CompSolid shape
187     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aFeature);
188     if (aResult.get()) {
189       ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(aResult);
190       if (aCompSolid.get()) {
191         GeomShapePtr aShape = aCompSolid->shape();
192         if (aShape.get() && aShape->isEqual(thePrs->shape())) {
193           thePrs->setObject(aCompSolid);
194           return;
195         }
196       }
197     }
198   }
199   thePrs->setObject(aFeature);
200 }
201
202 QList<ModuleBase_ViewerPrsPtr> XGUI_Selection::getHighlighted() const
203 {
204   QList<ModuleBase_ViewerPrsPtr> aPresentations;
205   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
206   if (aContext.IsNull())
207     return aPresentations;
208
209   QList<long> aSelectedIds; // Remember of selected address in order to avoid duplicates
210   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
211   for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) {
212     ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs());
213     Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive();
214     if (aSelectedIds.contains((long)anIO.Access()))
215       continue;
216     
217     aSelectedIds.append((long)anIO.Access());
218     aPrs->setInteractive(anIO);
219
220     ObjectPtr aResult = aDisplayer->getObject(anIO);
221     // we should not check the appearance of this feature because there can be some selected shapes
222     // for one feature
223     aPrs->setObject(aResult);
224     if (aContext->HasOpenedContext()) {
225       TopoDS_Shape aShape = aContext->DetectedShape();
226       if (!aShape.IsNull()) {
227         std::shared_ptr<GeomAPI_Shape> aGeomShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
228         aGeomShape->setImpl(new TopoDS_Shape(aShape));
229         aPrs->setShape(aGeomShape);
230       }
231     }
232     aPresentations.push_back(aPrs);
233   }
234   return aPresentations;
235 }
236
237 QObjectPtrList XGUI_Selection::selectedObjects() const
238 {
239   return myWorkshop->objectBrowser()->selectedObjects();
240 }
241
242 void XGUI_Selection::setSelectedObjects( const QObjectPtrList& theObjects ) const
243 {
244   return myWorkshop->objectBrowser()->setObjectsSelected( theObjects );
245 }
246
247 QObjectPtrList XGUI_Selection::selectedPresentations() const
248 {
249   QObjectPtrList aSelectedList;
250
251   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
252   if (!aContext.IsNull()) {
253     for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
254       Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
255       ObjectPtr aResult = myWorkshop->displayer()->getObject(anIO);
256       if (aResult)
257         aSelectedList.append(aResult);
258     }
259   }
260   return aSelectedList;
261 }
262
263 //**************************************************************
264 QModelIndexList XGUI_Selection::selectedIndexes() const
265 {
266   return myWorkshop->objectBrowser()->selectedIndexes();
267 }
268
269 //**************************************************************
270 void XGUI_Selection::selectedAISObjects(AIS_ListOfInteractive& theList) const
271 {
272   theList.Clear();
273
274   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
275   if (!aContext.IsNull()) {
276     for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
277       theList.Append(aContext->SelectedInteractive());
278   }
279 }
280
281 //**************************************************************
282 ObjectPtr XGUI_Selection::getSelectableObject(const Handle(SelectMgr_EntityOwner)& theOwner) const
283 {
284   ObjectPtr anObject;
285
286   Handle(SelectMgr_EntityOwner) aEO = theOwner;
287   if (!aEO.IsNull()) {
288     Handle(AIS_InteractiveObject) anObj = 
289       Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable());
290     anObject = myWorkshop->displayer()->getObject(anObj);
291   }
292   return anObject;
293 }
294
295 //**************************************************************
296 void XGUI_Selection::selectedShapes(NCollection_List<TopoDS_Shape>& theList, 
297                                     std::list<ObjectPtr>& theOwners) const
298 {
299   theList.Clear();
300   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
301   if (aContext.IsNull())
302     return;
303
304   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
305     TopoDS_Shape aShape = aContext->SelectedShape();
306     if (aShape.IsNull()) {
307       aShape = findAxisShape(aContext->SelectedInteractive());
308     }
309     if (!aShape.IsNull()) {
310       theList.Append(aShape);
311       Handle(SelectMgr_EntityOwner) aEO = aContext->SelectedOwner();
312       if (!aEO.IsNull()) {
313         Handle(AIS_InteractiveObject) anObj = 
314           Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable());
315         ObjectPtr anObject = myWorkshop->displayer()->getObject(anObj);
316         theOwners.push_back(anObject);
317       }
318     }
319   }
320 }
321
322 //**************************************************************
323 void XGUI_Selection::selectedOwners(SelectMgr_IndexedMapOfOwner& theSelectedOwners) const
324 {
325   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
326   if (!aContext.IsNull()) {
327     for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
328       theSelectedOwners.Add(aContext->SelectedOwner());
329     }
330   }
331 }
332
333 //**************************************************************
334 void XGUI_Selection::entityOwners(const Handle(AIS_InteractiveObject)& theObject,
335                                   SelectMgr_IndexedMapOfOwner& theOwners) const
336 {
337   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
338   if (aContext.IsNull() || theObject.IsNull())
339     return;
340
341   TColStd_ListOfInteger aModes;
342   aContext->ActivatedModes(theObject, aModes);
343
344   TColStd_ListIteratorOfListOfInteger anIt(aModes);
345   for (; anIt.More(); anIt.Next()) {
346     int aMode = anIt.Value();
347     if (!theObject->HasSelection(aMode))
348       continue;
349
350     Handle(SelectMgr_Selection) aSelection = theObject->Selection(aMode);
351     for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
352       Handle(SelectMgr_SensitiveEntity) anEntity = aSelection->Sensitive();
353       if (anEntity.IsNull())
354         continue;
355       Handle(SelectMgr_EntityOwner) anOwner =
356         Handle(SelectMgr_EntityOwner)::DownCast(anEntity->BaseSensitive()->OwnerId());
357       if (!anOwner.IsNull())
358         theOwners.Add(anOwner);
359     }
360   }
361 }
362
363 //**************************************************************
364 TopoDS_Shape XGUI_Selection::findAxisShape(Handle(AIS_InteractiveObject) theIO) const
365 {
366   TopoDS_Shape aShape;
367   // Fill by trihedron shapes
368   Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(theIO);
369   if (!aAxis.IsNull()) {
370     // an Axis from Trihedron
371     Handle(Geom_Line) aLine = aAxis->Component();
372     Handle(Prs3d_DatumAspect) DA = aAxis->Attributes()->DatumAspect();
373     Handle(Geom_TrimmedCurve) aTLine = new Geom_TrimmedCurve(aLine, 0, DA->FirstAxisLength());
374
375     BRep_Builder aBuilder;      
376     TopoDS_Edge aEdge;
377     aBuilder.MakeEdge(aEdge, aTLine, Precision::Confusion());
378     if (!aEdge.IsNull())
379       aShape = aEdge;
380   } else {
381     Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(theIO);
382     if (!aPoint.IsNull()) {
383       // A point from trihedron
384       Handle(Geom_Point) aPnt = aPoint->Component();
385       BRep_Builder aBuilder;
386       TopoDS_Vertex aVertex;
387       aBuilder.MakeVertex(aVertex, aPnt->Pnt(), Precision::Confusion());
388       if (!aVertex.IsNull())
389         aShape = aVertex;
390     }
391   }
392   return aShape;
393 }