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