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