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::RedisplayInLocalContext(boost::shared_ptr<ModelAPI_Feature> theFeature,
103                                              const TopoDS_Shape& theShape,
104                                              const std::list<int>& theModes, const bool isUpdateViewer)
105 {
106   Handle(AIS_InteractiveContext) aContext = AISContext();
107   // Open local context if there is no one
108   if (!aContext->HasOpenedContext()) {
109     aContext->ClearCurrents(false);
110     aContext->OpenLocalContext(false/*use displayed objects*/, /*true*/false/*use displayed objects*/,
111                          true/*allow shape decomposition*/);
112   }
113   // display or redisplay presentation
114   Handle(AIS_Shape) anAIS;
115   if (IsVisible(theFeature)) {
116     anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[theFeature]);
117     if (!anAIS.IsNull()) {
118       // if the AIS object is displayed in the opened local context in some mode, additional
119       // AIS sub objects are created there. They should be rebuild for correct selecting.
120       // It is possible to correct it by closing local context before the shape set and opening
121       // after. Another workaround to thrown down the selection and reselecting the AIS.
122       // If there was a problem here, try the first solution with close/open local context.
123       anAIS->Set(theShape);
124       anAIS->Redisplay();
125       if (aContext->IsSelected(anAIS)) {
126         aContext->AddOrRemoveSelected(anAIS, false);
127         aContext->AddOrRemoveSelected(anAIS, false);
128         //aContext->SetSelected(anAIS, false);
129       }
130     }
131   }
132   else {
133     anAIS = new AIS_Shape(theShape);
134     myFeature2AISObjectMap[theFeature] = anAIS;
135     aContext->Display(anAIS, false);
136   }
137   // Activate selection of objects from prs
138   if (!anAIS.IsNull()) {
139     aContext->Load(anAIS, -1, true/*allow decomposition*/);
140     std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
141     for (; anIt != aLast; anIt++)
142     {
143       aContext->Activate(anAIS, AIS_Shape::SelectionMode((TopAbs_ShapeEnum)*anIt));
144     }
145   }
146
147   if (isUpdateViewer)
148     aContext->UpdateCurrentViewer();
149 }
150
151 void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
152 {
153   Handle(AIS_InteractiveContext) ic = AISContext();
154
155   AIS_ListOfInteractive aList;
156   ic->DisplayedObjects(aList);
157   AIS_ListIteratorOfListOfInteractive anIter(aList);
158   for (; anIter.More(); anIter.Next()) {
159     if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
160       continue;
161
162     // erase an object
163     Handle(AIS_InteractiveObject) anIO = anIter.Value();
164     ic->Erase(anIO, false);
165   }
166   myFeature2AISObjectMap.clear();
167   if (isUpdateViewer)
168     ic->UpdateCurrentViewer();
169 }
170
171 void XGUI_Displayer::EraseDeletedFeatures(const bool isUpdateViewer)
172 {
173   Handle(AIS_InteractiveContext) aContext = AISContext();
174
175   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
176                                   aFLast = myFeature2AISObjectMap.end();
177   std::list<boost::shared_ptr<ModelAPI_Feature>> aRemoved;
178   for (; aFIt != aFLast; aFIt++)
179   {
180     boost::shared_ptr<ModelAPI_Feature> aFeature = (*aFIt).first;
181     if (!aFeature || !aFeature->data()->isValid()) {
182       Handle(AIS_InteractiveObject) anAIS = (*aFIt).second;
183       if (!anAIS.IsNull()) {
184         aContext->Erase(anAIS, false);
185         aRemoved.push_back(aFeature);
186       }
187     }
188   }
189   std::list<boost::shared_ptr<ModelAPI_Feature>>::const_iterator anIt = aRemoved.begin(),
190                                                                  aLast = aRemoved.end();
191   for (; anIt != aLast; anIt++) {
192     myFeature2AISObjectMap.erase(myFeature2AISObjectMap.find(*anIt));
193   }
194
195   if (isUpdateViewer)
196     aContext->UpdateCurrentViewer();
197 }
198
199 void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer)
200 {
201   closeAllContexts(true);
202 }
203
204 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
205 {
206   Handle(AIS_InteractiveContext) ic = AISContext();
207   if (!ic.IsNull()) {
208     ic->CloseAllContexts(false);
209     if (isUpdateViewer)
210       ic->UpdateCurrentViewer();
211   }
212 }
213
214 void XGUI_Displayer::UpdateViewer()
215 {
216   Handle(AIS_InteractiveContext) ic = AISContext();
217   if (!ic.IsNull())
218     ic->UpdateCurrentViewer();
219 }
220
221 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const 
222
223   return myWorkshop->viewer()->AISContext(); 
224 }