]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_Displayer.cpp
Salome HOME
Intermediate changes for sketch builder
[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     UpdateViewer();
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     UpdateViewer();
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(Standard_True);
144       aContext->RecomputeSelectionOnly(anAIS);
145     }
146   }
147   else {
148     anAIS = new AIS_Shape(theShape);
149     myFeature2AISObjectMap[theFeature] = anAIS;
150     aContext->Display(anAIS, false);
151   }
152   if (isUpdateViewer)
153     UpdateViewer();
154 }
155
156 void XGUI_Displayer::ActivateInLocalContext(boost::shared_ptr<ModelAPI_Feature> theFeature,
157                                          const std::list<int>& theModes, const bool isUpdateViewer)
158 {
159   Handle(AIS_InteractiveContext) aContext = AISContext();
160   // Open local context if there is no one
161   if (!aContext->HasOpenedContext()) {
162     aContext->ClearCurrents(false);
163     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
164   }
165   // display or redisplay presentation
166   Handle(AIS_Shape) anAIS;
167   if (IsVisible(theFeature))
168     anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[theFeature]);
169
170   // Activate selection of objects from prs
171   if (!anAIS.IsNull()) {
172         aContext->Load(anAIS, -1, true/*allow decomposition*/);
173     aContext->Deactivate(anAIS);
174
175     std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
176     for (; anIt != aLast; anIt++)
177     {
178       aContext->Activate(anAIS, AIS_Shape::SelectionMode((TopAbs_ShapeEnum)*anIt));
179         }
180   }
181
182   if (isUpdateViewer)
183     UpdateViewer();
184 }
185
186 void XGUI_Displayer::StopSelection(const std::list<XGUI_ViewerPrs>& theFeatures, const bool isStop,
187                                    const bool isUpdateViewer)
188 {
189   Handle(AIS_InteractiveContext) aContext = AISContext();
190
191   Handle(AIS_Shape) anAIS;
192   std::list<XGUI_ViewerPrs>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
193   boost::shared_ptr<ModelAPI_Feature> aFeature;
194   for (; anIt != aLast; anIt++) {
195     aFeature = (*anIt).feature();
196     if (IsVisible(aFeature))
197       anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[aFeature]);
198     if (anAIS.IsNull())
199       continue;
200
201     if (isStop) {
202       QColor aColor(Qt::white);
203       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
204       anAIS->Redisplay();
205     }
206     else {
207       QColor aColor(Qt::red);
208       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
209       anAIS->Redisplay();
210     }
211   }
212   if (isUpdateViewer)
213     UpdateViewer();
214 }
215
216 void XGUI_Displayer::SetSelected(const std::list<XGUI_ViewerPrs>& theFeatures, const bool isUpdateViewer)
217 {
218   Handle(AIS_InteractiveContext) aContext = AISContext();
219
220   std::list<XGUI_ViewerPrs>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
221   boost::shared_ptr<ModelAPI_Feature> aFeature;
222
223   Handle(AIS_Shape) anAIS;
224   // we need to unhighligth objects manually in the current local context
225   // in couple with the selection clear (TODO)
226   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
227   if (!aLocalContext.IsNull())
228     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
229   aContext->ClearSelected(false);
230
231   for (; anIt != aLast; anIt++) {
232     aFeature = (*anIt).feature();
233     if (IsVisible(aFeature))
234       anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[aFeature]);
235     if (anAIS.IsNull())
236       continue;
237     aContext->AddOrRemoveSelected(anAIS, false);
238   }
239  
240   if (isUpdateViewer)
241     UpdateViewer();
242 }
243
244 void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
245 {
246   Handle(AIS_InteractiveContext) ic = AISContext();
247
248   AIS_ListOfInteractive aList;
249   ic->DisplayedObjects(aList);
250   AIS_ListIteratorOfListOfInteractive anIter(aList);
251   for (; anIter.More(); anIter.Next()) {
252     if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
253       continue;
254
255     // erase an object
256     Handle(AIS_InteractiveObject) anIO = anIter.Value();
257     ic->Erase(anIO, false);
258   }
259   myFeature2AISObjectMap.clear();
260   if (isUpdateViewer)
261     UpdateViewer();
262 }
263
264 void XGUI_Displayer::EraseDeletedFeatures(const bool isUpdateViewer)
265 {
266   Handle(AIS_InteractiveContext) aContext = AISContext();
267
268   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
269                                   aFLast = myFeature2AISObjectMap.end();
270   std::list<boost::shared_ptr<ModelAPI_Feature>> aRemoved;
271   for (; aFIt != aFLast; aFIt++)
272   {
273     boost::shared_ptr<ModelAPI_Feature> aFeature = (*aFIt).first;
274     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
275       Handle(AIS_InteractiveObject) anAIS = (*aFIt).second;
276       if (!anAIS.IsNull()) {
277         aContext->Erase(anAIS, false);
278         aRemoved.push_back(aFeature);
279       }
280     }
281   }
282   std::list<boost::shared_ptr<ModelAPI_Feature>>::const_iterator anIt = aRemoved.begin(),
283                                                                  aLast = aRemoved.end();
284   for (; anIt != aLast; anIt++) {
285     myFeature2AISObjectMap.erase(myFeature2AISObjectMap.find(*anIt));
286   }
287
288   if (isUpdateViewer)
289     UpdateViewer();
290 }
291
292 void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer)
293 {
294   CloseAllContexts(true);
295 }
296
297 Handle(AIS_InteractiveObject) XGUI_Displayer::GetAISObject(
298                                               boost::shared_ptr<ModelAPI_Feature> theFeature) const
299 {
300   Handle(AIS_InteractiveObject) anIO;
301   if (myFeature2AISObjectMap.find(theFeature) != myFeature2AISObjectMap.end())
302     anIO = (myFeature2AISObjectMap.find(theFeature))->second;
303   return anIO;
304 }
305
306 boost::shared_ptr<ModelAPI_Feature> XGUI_Displayer::GetFeature(Handle(AIS_InteractiveObject) theIO) const
307 {
308   boost::shared_ptr<ModelAPI_Feature> aFeature;
309   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
310                                   aFLast = myFeature2AISObjectMap.end();
311   for (; aFIt != aFLast && !aFeature; aFIt++) {
312     Handle(AIS_InteractiveObject) anAIS = (*aFIt).second;
313     if (anAIS != theIO)
314       continue;
315     aFeature = (*aFIt).first;
316   }
317   return aFeature;
318 }
319
320 void XGUI_Displayer::CloseAllContexts(const bool isUpdateViewer)
321 {
322   Handle(AIS_InteractiveContext) ic = AISContext();
323   if (!ic.IsNull()) {
324     ic->CloseAllContexts(false);
325     if (isUpdateViewer)
326       UpdateViewer();
327   }
328 }
329
330 void XGUI_Displayer::UpdateViewer()
331 {
332   Handle(AIS_InteractiveContext) ic = AISContext();
333   if (!ic.IsNull())
334     ic->UpdateCurrentViewer();
335 }
336
337 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const 
338
339   return myWorkshop->viewer()->AISContext(); 
340 }