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_ListOfInteractive.hxx>
16 #include <AIS_ListIteratorOfListOfInteractive.hxx>
17
18 #include <AIS_Shape.hxx>
19
20 #include <set>
21
22 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
23 {
24   myWorkshop = theWorkshop;
25 }
26
27 XGUI_Displayer::~XGUI_Displayer()
28 {
29 }
30
31 bool XGUI_Displayer::IsVisible(boost::shared_ptr<ModelAPI_Feature> theFeature)
32 {
33   return myFeature2AISObjectMap.find(theFeature) != myFeature2AISObjectMap.end();
34 }
35
36 void XGUI_Displayer::Display(boost::shared_ptr<ModelAPI_Feature> theFeature,
37                              const bool isUpdateViewer)
38 {
39 }
40
41 /*void XGUI_Displayer::Display(boost::shared_ptr<ModelAPI_Feature> theFeature,
42                              const TopoDS_Shape& theShape, const bool isUpdateViewer)
43 {
44   Handle(AIS_InteractiveContext) aContext = AISContext();
45
46   Handle(AIS_Shape) anAIS = new AIS_Shape(theShape);
47   myFeature2AISObjectMap[theFeature] = anAIS;
48
49   aContext->Display(anAIS, Standard_False);
50   if (isUpdateViewer)
51     aContext->UpdateCurrentViewer();
52 }*/
53
54
55 std::list<XGUI_ViewerPrs> XGUI_Displayer::GetViewerPrs()
56 {
57   std::set<boost::shared_ptr<ModelAPI_Feature> > aPrsFeatures;
58   std::list<XGUI_ViewerPrs> aPresentations;
59
60   Handle(AIS_InteractiveContext) aContext = AISContext();
61   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
62     Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
63     TopoDS_Shape aShape = aContext->SelectedShape();
64
65     boost::shared_ptr<ModelAPI_Feature> aFeature;
66     FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
67                                     aFLast = myFeature2AISObjectMap.end();
68     for (; aFIt != aFLast && !aFeature; aFIt++) {
69       Handle(AIS_InteractiveObject) anAIS = (*aFIt).second;
70       if (anAIS != anIO)
71         continue;
72       aFeature = (*aFIt).first;
73     }
74     if (aPrsFeatures.find(aFeature) != aPrsFeatures.end())
75       continue;
76     aPresentations.push_back(XGUI_ViewerPrs(aFeature, aShape));
77     aPrsFeatures.insert(aFeature);
78   }
79
80   return aPresentations;
81 }
82
83 void XGUI_Displayer::Erase(boost::shared_ptr<ModelAPI_Feature> theFeature,
84                            const bool isUpdateViewer)
85 {
86   if (myFeature2AISObjectMap.find(theFeature) == myFeature2AISObjectMap.end())
87     return;
88
89   Handle(AIS_InteractiveContext) aContext = AISContext();
90   Handle(AIS_InteractiveObject) anAIS = myFeature2AISObjectMap[theFeature];
91   Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast(anAIS);
92   if (!anAISShape.IsNull())
93   {
94     aContext->Erase(anAISShape);
95   }
96   myFeature2AISObjectMap.erase(theFeature);
97
98   if (isUpdateViewer)
99     aContext->UpdateCurrentViewer();
100 }
101
102 void XGUI_Displayer::Redisplay(boost::shared_ptr<ModelAPI_Feature> theFeature,
103                                const TopoDS_Shape& theShape, const bool isUpdateViewer)
104 {
105   Handle(AIS_InteractiveContext) aContext = AISContext();
106   // Open local context if there is no one
107   if (!aContext->HasOpenedContext()) {
108     aContext->ClearCurrents(false);
109     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
110   }
111   // display or redisplay presentation
112   Handle(AIS_Shape) anAIS;
113   if (IsVisible(theFeature)) {
114     anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[theFeature]);
115     if (!anAIS.IsNull()) {
116       // if the AIS object is displayed in the opened local context in some mode, additional
117       // AIS sub objects are created there. They should be rebuild for correct selecting.
118       // It is possible to correct it by closing local context before the shape set and opening
119       // after. Another workaround to thrown down the selection and reselecting the AIS.
120       // If there was a problem here, try the first solution with close/open local context.
121       anAIS->Set(theShape);
122       anAIS->Redisplay();
123       /*if (aContext->IsSelected(anAIS)) {
124         aContext->AddOrRemoveSelected(anAIS, false);
125         aContext->AddOrRemoveSelected(anAIS, false);
126         //aContext->SetSelected(anAIS, false);
127       }*/
128     }
129   }
130   else {
131     anAIS = new AIS_Shape(theShape);
132     myFeature2AISObjectMap[theFeature] = anAIS;
133     aContext->Display(anAIS, false);
134   }
135 }
136
137 void XGUI_Displayer::ActivateInLocalContext(boost::shared_ptr<ModelAPI_Feature> theFeature,
138                                          const std::list<int>& theModes, const bool isUpdateViewer)
139 {
140   Handle(AIS_InteractiveContext) aContext = AISContext();
141   // Open local context if there is no one
142   if (!aContext->HasOpenedContext()) {
143     aContext->ClearCurrents(false);
144     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
145   }
146   // display or redisplay presentation
147   Handle(AIS_Shape) anAIS;
148   if (IsVisible(theFeature))
149     anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[theFeature]);
150   //if (!anAIS.IsNull())
151   //  return;
152
153   // Activate selection of objects from prs
154   if (!anAIS.IsNull()) {
155         aContext->Load(anAIS, -1, true/*allow decomposition*/);
156     aContext->Deactivate(anAIS);
157
158     std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
159     QString aDebugStr = QString(featureInfo(theFeature).c_str()) + QString("; modes: ");
160     for (; anIt != aLast; anIt++)
161     {
162       aContext->Activate(anAIS, AIS_Shape::SelectionMode((TopAbs_ShapeEnum)*anIt));
163           aDebugStr += QString("%1").arg(AIS_Shape::SelectionMode((TopAbs_ShapeEnum)*anIt)) + QString(", ");
164         }
165     /*if (theModes.empty()) {
166       aContext->Deactivate(anAIS);
167       aContext->Activate(anAIS, -1);
168           aContext->ClearSelected();
169           aDebugStr += " deactivated";
170           QColor aColor(Qt::white);
171           anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
172         }*/
173         qDebug(aDebugStr.toStdString().c_str());
174   }
175
176   if (isUpdateViewer)
177     aContext->UpdateCurrentViewer();
178 }
179
180 void XGUI_Displayer::StopSelection(const std::list<XGUI_ViewerPrs>& theFeatures, const bool isStop)
181 {
182   return;
183   Handle(AIS_InteractiveContext) aContext = AISContext();
184
185   Handle(AIS_Shape) anAIS;
186   std::list<XGUI_ViewerPrs>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
187   boost::shared_ptr<ModelAPI_Feature> aFeature;
188   for (; anIt != aLast; anIt++) {
189     aFeature = (*anIt).feature();
190     if (IsVisible(aFeature))
191       anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[aFeature]);
192     if (anAIS.IsNull())
193       continue;
194
195     if (isStop) {
196       aContext->Deactivate(anAIS);
197       aContext->Activate(anAIS, -1);
198       aContext->ClearSelected();
199       
200       //aDebugStr += " deactivated";
201       QColor aColor(Qt::white);
202       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
203     }
204     else {
205       //QColor aColor(Qt::red);
206       //anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
207     }
208   }
209 }
210
211 void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
212 {
213   Handle(AIS_InteractiveContext) ic = AISContext();
214
215   AIS_ListOfInteractive aList;
216   ic->DisplayedObjects(aList);
217   AIS_ListIteratorOfListOfInteractive anIter(aList);
218   for (; anIter.More(); anIter.Next()) {
219     if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
220       continue;
221
222     // erase an object
223     Handle(AIS_InteractiveObject) anIO = anIter.Value();
224     ic->Erase(anIO, false);
225   }
226   myFeature2AISObjectMap.clear();
227   if (isUpdateViewer)
228     ic->UpdateCurrentViewer();
229 }
230
231 void XGUI_Displayer::EraseDeletedFeatures(const bool isUpdateViewer)
232 {
233   Handle(AIS_InteractiveContext) aContext = AISContext();
234
235   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
236                                   aFLast = myFeature2AISObjectMap.end();
237   std::list<boost::shared_ptr<ModelAPI_Feature>> aRemoved;
238   for (; aFIt != aFLast; aFIt++)
239   {
240     boost::shared_ptr<ModelAPI_Feature> aFeature = (*aFIt).first;
241     if (!aFeature || !aFeature->data()->isValid()) {
242       Handle(AIS_InteractiveObject) anAIS = (*aFIt).second;
243       if (!anAIS.IsNull()) {
244         aContext->Erase(anAIS, false);
245         aRemoved.push_back(aFeature);
246       }
247     }
248   }
249   std::list<boost::shared_ptr<ModelAPI_Feature>>::const_iterator anIt = aRemoved.begin(),
250                                                                  aLast = aRemoved.end();
251   for (; anIt != aLast; anIt++) {
252     myFeature2AISObjectMap.erase(myFeature2AISObjectMap.find(*anIt));
253   }
254
255   if (isUpdateViewer)
256     aContext->UpdateCurrentViewer();
257 }
258
259 void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer)
260 {
261   closeAllContexts(true);
262 }
263
264 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
265 {
266   Handle(AIS_InteractiveContext) ic = AISContext();
267   if (!ic.IsNull()) {
268     ic->CloseAllContexts(false);
269     if (isUpdateViewer)
270       ic->UpdateCurrentViewer();
271   }
272 }
273
274 void XGUI_Displayer::UpdateViewer()
275 {
276   Handle(AIS_InteractiveContext) ic = AISContext();
277   if (!ic.IsNull())
278     ic->UpdateCurrentViewer();
279 }
280
281 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const 
282
283   return myWorkshop->viewer()->AISContext(); 
284 }