Salome HOME
Merge branch 'master' of newgeom:newgeom
[modules/shaper.git] / src / XGUI / XGUI_Displayer.cpp
1 // File:        XGUI_Displayer.cpp
2 // Created:     20 Apr 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include "XGUI_Displayer.h"
6 #include "XGUI_Viewer.h"
7 #include "XGUI_Workshop.h"
8 #include "XGUI_ViewerProxy.h"
9 #include "XGUI_Tools.h"
10
11 #include <ModelAPI_Document.h>
12 #include <ModelAPI_Data.h>
13
14 #include <AIS_InteractiveContext.hxx>
15 #include <AIS_LocalContext.hxx>
16 #include <AIS_ListOfInteractive.hxx>
17 #include <AIS_ListIteratorOfListOfInteractive.hxx>
18
19 #include <AIS_Shape.hxx>
20
21 #include <set>
22
23 const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse selection sensitivity
24
25 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
26 {
27   myWorkshop = theWorkshop;
28 }
29
30 XGUI_Displayer::~XGUI_Displayer()
31 {
32 }
33
34 bool XGUI_Displayer::IsVisible(boost::shared_ptr<ModelAPI_Feature> theFeature)
35 {
36   return myFeature2AISObjectMap.find(theFeature) != myFeature2AISObjectMap.end();
37 }
38
39 void XGUI_Displayer::Display(boost::shared_ptr<ModelAPI_Feature> theFeature,
40                              const bool isUpdateViewer)
41 {
42 }
43
44 /*void XGUI_Displayer::Display(boost::shared_ptr<ModelAPI_Feature> theFeature,
45                              const TopoDS_Shape& theShape, const bool isUpdateViewer)
46 {
47   Handle(AIS_InteractiveContext) aContext = AISContext();
48
49   Handle(AIS_Shape) anAIS = new AIS_Shape(theShape);
50   myFeature2AISObjectMap[theFeature] = anAIS;
51
52   aContext->Display(anAIS, Standard_False);
53   if (isUpdateViewer)
54     aContext->UpdateCurrentViewer();
55 }*/
56
57
58 std::list<XGUI_ViewerPrs> XGUI_Displayer::GetSelected(const int theShapeTypeToSkip)
59 {
60   std::set<boost::shared_ptr<ModelAPI_Feature> > aPrsFeatures;
61   std::list<XGUI_ViewerPrs> aPresentations;
62
63   Handle(AIS_InteractiveContext) aContext = AISContext();
64   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
65     Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
66     TopoDS_Shape aShape = aContext->SelectedShape();
67     if (theShapeTypeToSkip >= 0 && !aShape.IsNull() && aShape.ShapeType() == theShapeTypeToSkip)
68       continue;
69
70     boost::shared_ptr<ModelAPI_Feature> aFeature = GetFeature(anIO);
71     if (aPrsFeatures.find(aFeature) != aPrsFeatures.end())
72       continue;
73     aPresentations.push_back(XGUI_ViewerPrs(aFeature, aShape));
74     aPrsFeatures.insert(aFeature);
75   }
76   return aPresentations;
77 }
78
79 std::list<XGUI_ViewerPrs> XGUI_Displayer::GetHighlighted(const int theShapeTypeToSkip)
80 {
81   std::set<boost::shared_ptr<ModelAPI_Feature> > aPrsFeatures;
82   std::list<XGUI_ViewerPrs> aPresentations;
83
84   Handle(AIS_InteractiveContext) aContext = AISContext();
85   for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) {
86     Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive();
87     TopoDS_Shape aShape = aContext->DetectedShape();
88     if (theShapeTypeToSkip >= 0 && !aShape.IsNull() && aShape.ShapeType() == theShapeTypeToSkip)
89       continue;
90
91     boost::shared_ptr<ModelAPI_Feature> aFeature = GetFeature(anIO);
92     if (aPrsFeatures.find(aFeature) != aPrsFeatures.end())
93       continue;
94     aPresentations.push_back(XGUI_ViewerPrs(aFeature, aShape));
95     aPrsFeatures.insert(aFeature);
96   }
97
98   return aPresentations;
99 }
100
101 void XGUI_Displayer::Erase(boost::shared_ptr<ModelAPI_Feature> theFeature,
102                            const bool isUpdateViewer)
103 {
104   if (myFeature2AISObjectMap.find(theFeature) == myFeature2AISObjectMap.end())
105     return;
106
107   Handle(AIS_InteractiveContext) aContext = AISContext();
108   Handle(AIS_InteractiveObject) anAIS = myFeature2AISObjectMap[theFeature];
109   Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast(anAIS);
110   if (!anAISShape.IsNull())
111   {
112     aContext->Erase(anAISShape);
113   }
114   myFeature2AISObjectMap.erase(theFeature);
115
116   if (isUpdateViewer)
117     aContext->UpdateCurrentViewer();
118 }
119
120 void XGUI_Displayer::Redisplay(boost::shared_ptr<ModelAPI_Feature> theFeature,
121                                const TopoDS_Shape& theShape, const bool isUpdateViewer)
122 {
123   Handle(AIS_InteractiveContext) aContext = AISContext();
124   // Open local context if there is no one
125   if (!aContext->HasOpenedContext()) {
126     aContext->ClearCurrents(false);
127     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
128     // set mouse sensitivity
129     //aContext->SetSensitivityMode(StdSelect_SM_WINDOW);
130     //aContext->SetPixelTolerance(MOUSE_SENSITIVITY_IN_PIXEL);
131   }
132   // display or redisplay presentation
133   Handle(AIS_Shape) anAIS;
134   if (IsVisible(theFeature)) {
135     anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[theFeature]);
136     if (!anAIS.IsNull()) {
137       // if the AIS object is displayed in the opened local context in some mode, additional
138       // AIS sub objects are created there. They should be rebuild for correct selecting.
139       // It is possible to correct it by closing local context before the shape set and opening
140       // after. Another workaround to thrown down the selection and reselecting the AIS.
141       // If there was a problem here, try the first solution with close/open local context.
142       anAIS->Set(theShape);
143       anAIS->Redisplay();
144
145       /*if (aContext->IsSelected(anAIS)) {
146         aContext->AddOrRemoveSelected(anAIS, false);
147         aContext->AddOrRemoveSelected(anAIS, false);
148         //aContext->SetSelected(anAIS, false);
149       }*/
150     }
151   }
152   else {
153     anAIS = new AIS_Shape(theShape);
154     myFeature2AISObjectMap[theFeature] = anAIS;
155     aContext->Display(anAIS, false);
156   }
157 }
158
159 void XGUI_Displayer::ActivateInLocalContext(boost::shared_ptr<ModelAPI_Feature> theFeature,
160                                          const std::list<int>& theModes, const bool isUpdateViewer)
161 {
162   Handle(AIS_InteractiveContext) aContext = AISContext();
163   // Open local context if there is no one
164   if (!aContext->HasOpenedContext()) {
165     aContext->ClearCurrents(false);
166     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
167   }
168   // display or redisplay presentation
169   Handle(AIS_Shape) anAIS;
170   if (IsVisible(theFeature))
171     anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[theFeature]);
172
173   // Activate selection of objects from prs
174   if (!anAIS.IsNull()) {
175         aContext->Load(anAIS, -1, true/*allow decomposition*/);
176     aContext->Deactivate(anAIS);
177
178     std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
179     for (; anIt != aLast; anIt++)
180     {
181       aContext->Activate(anAIS, AIS_Shape::SelectionMode((TopAbs_ShapeEnum)*anIt));
182         }
183   }
184
185   if (isUpdateViewer)
186     aContext->UpdateCurrentViewer();
187 }
188
189 void XGUI_Displayer::StopSelection(const std::list<XGUI_ViewerPrs>& theFeatures, const bool isStop,
190                                    const bool isUpdateViewer)
191 {
192   Handle(AIS_InteractiveContext) aContext = AISContext();
193
194   Handle(AIS_Shape) anAIS;
195   std::list<XGUI_ViewerPrs>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
196   boost::shared_ptr<ModelAPI_Feature> aFeature;
197   for (; anIt != aLast; anIt++) {
198     aFeature = (*anIt).feature();
199     if (IsVisible(aFeature))
200       anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[aFeature]);
201     if (anAIS.IsNull())
202       continue;
203
204     if (isStop) {
205       QColor aColor(Qt::white);
206       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
207       anAIS->Redisplay();
208     }
209     else {
210       QColor aColor(Qt::red);
211       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
212       anAIS->Redisplay();
213     }
214   }
215   if (isUpdateViewer)
216     aContext->UpdateCurrentViewer();
217 }
218
219 void XGUI_Displayer::SetSelected(const std::list<XGUI_ViewerPrs>& theFeatures, const bool isUpdateViewer)
220 {
221   Handle(AIS_InteractiveContext) aContext = AISContext();
222
223   std::list<XGUI_ViewerPrs>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
224   boost::shared_ptr<ModelAPI_Feature> aFeature;
225
226   Handle(AIS_Shape) anAIS;
227   // we need to unhighligth objects manually in the current local context
228   // in couple with the selection clear (TODO)
229   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
230   if (!aLocalContext.IsNull())
231     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
232   aContext->ClearSelected(false);
233
234   for (; anIt != aLast; anIt++) {
235     aFeature = (*anIt).feature();
236     if (IsVisible(aFeature))
237       anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[aFeature]);
238     if (anAIS.IsNull())
239       continue;
240     aContext->AddOrRemoveSelected(anAIS, false);
241   }
242  
243   if (isUpdateViewer)
244     aContext->UpdateCurrentViewer();
245 }
246
247 void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
248 {
249   Handle(AIS_InteractiveContext) ic = AISContext();
250
251   AIS_ListOfInteractive aList;
252   ic->DisplayedObjects(aList);
253   AIS_ListIteratorOfListOfInteractive anIter(aList);
254   for (; anIter.More(); anIter.Next()) {
255     if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
256       continue;
257
258     // erase an object
259     Handle(AIS_InteractiveObject) anIO = anIter.Value();
260     ic->Erase(anIO, false);
261   }
262   myFeature2AISObjectMap.clear();
263   if (isUpdateViewer)
264     ic->UpdateCurrentViewer();
265 }
266
267 void XGUI_Displayer::EraseDeletedFeatures(const bool isUpdateViewer)
268 {
269   Handle(AIS_InteractiveContext) aContext = AISContext();
270
271   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
272                                   aFLast = myFeature2AISObjectMap.end();
273   std::list<boost::shared_ptr<ModelAPI_Feature>> aRemoved;
274   for (; aFIt != aFLast; aFIt++)
275   {
276     boost::shared_ptr<ModelAPI_Feature> aFeature = (*aFIt).first;
277     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
278       Handle(AIS_InteractiveObject) anAIS = (*aFIt).second;
279       if (!anAIS.IsNull()) {
280         aContext->Erase(anAIS, false);
281         aRemoved.push_back(aFeature);
282       }
283     }
284   }
285   std::list<boost::shared_ptr<ModelAPI_Feature>>::const_iterator anIt = aRemoved.begin(),
286                                                                  aLast = aRemoved.end();
287   for (; anIt != aLast; anIt++) {
288     myFeature2AISObjectMap.erase(myFeature2AISObjectMap.find(*anIt));
289   }
290
291   if (isUpdateViewer)
292     aContext->UpdateCurrentViewer();
293 }
294
295 void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer)
296 {
297   CloseAllContexts(true);
298 }
299
300 boost::shared_ptr<ModelAPI_Feature> XGUI_Displayer::GetFeature(Handle(AIS_InteractiveObject) theIO)
301 {
302   boost::shared_ptr<ModelAPI_Feature> aFeature;
303   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
304                                   aFLast = myFeature2AISObjectMap.end();
305   for (; aFIt != aFLast && !aFeature; aFIt++) {
306     Handle(AIS_InteractiveObject) anAIS = (*aFIt).second;
307     if (anAIS != theIO)
308       continue;
309     aFeature = (*aFIt).first;
310   }
311   return aFeature;
312 }
313
314 void XGUI_Displayer::CloseAllContexts(const bool isUpdateViewer)
315 {
316   Handle(AIS_InteractiveContext) ic = AISContext();
317   if (!ic.IsNull()) {
318     ic->CloseAllContexts(false);
319     if (isUpdateViewer)
320       ic->UpdateCurrentViewer();
321   }
322 }
323
324 void XGUI_Displayer::UpdateViewer()
325 {
326   Handle(AIS_InteractiveContext) ic = AISContext();
327   if (!ic.IsNull())
328     ic->UpdateCurrentViewer();
329 }
330
331 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const 
332
333   return myWorkshop->viewer()->AISContext(); 
334 }