Salome HOME
Create selection validator and selection object
[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 #include <ModelAPI_Object.h>
14
15 #include <GeomAPI_Shape.h>
16
17 #include <AIS_InteractiveContext.hxx>
18 #include <AIS_LocalContext.hxx>
19 #include <AIS_ListOfInteractive.hxx>
20 #include <AIS_ListIteratorOfListOfInteractive.hxx>
21 #include <AIS_DimensionSelectionMode.hxx>
22
23 #include <AIS_Shape.hxx>
24
25 #include <set>
26
27 const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse selection sensitivity
28
29 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
30 {
31   myWorkshop = theWorkshop;
32 }
33
34 XGUI_Displayer::~XGUI_Displayer()
35 {
36 }
37
38 bool XGUI_Displayer::isVisible(FeaturePtr theFeature)
39 {
40   FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature);
41   return myFeature2AISObjectMap.find(aFeature) != myFeature2AISObjectMap.end();
42 }
43
44 bool XGUI_Displayer::display(FeaturePtr theFeature, bool isUpdateViewer)
45 {
46   FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature);
47   boost::shared_ptr<GeomAPI_Shape> aShapePtr = aFeature->data()->shape();
48
49   if (aShapePtr) {
50     boost::shared_ptr<GeomAPI_AISObject> anAIS(new GeomAPI_AISObject());
51     anAIS->createShape(aShapePtr);
52     return display(aFeature, anAIS, isUpdateViewer);
53   }
54   return false;
55 }
56
57 bool XGUI_Displayer::display(FeaturePtr theFeature,
58                              boost::shared_ptr<GeomAPI_AISObject> theAIS, bool isUpdateViewer)
59 {
60   Handle(AIS_InteractiveContext) aContext = AISContext();
61
62   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
63   if (!anAISIO.IsNull()) {
64     myFeature2AISObjectMap[theFeature] = theAIS;
65     aContext->Display(anAISIO, isUpdateViewer);
66     return true;
67   }
68   return false;
69 }
70
71
72
73 void XGUI_Displayer::erase(FeaturePtr theFeature,
74                            const bool isUpdateViewer)
75 {
76   FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature);
77
78   if (myFeature2AISObjectMap.find(aFeature) == myFeature2AISObjectMap.end())
79     return;
80
81   Handle(AIS_InteractiveContext) aContext = AISContext();
82   boost::shared_ptr<GeomAPI_AISObject> anObject = myFeature2AISObjectMap[aFeature];
83   if (anObject)  {
84     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
85     if (!anAIS.IsNull()) {
86       aContext->Erase(anAIS, isUpdateViewer);
87       
88     }
89   }
90   myFeature2AISObjectMap.erase(aFeature);
91 }
92
93
94 bool XGUI_Displayer::redisplay(FeaturePtr theFeature,
95                                boost::shared_ptr<GeomAPI_AISObject> theAIS,
96                                const bool isUpdateViewer)
97 {
98   bool isCreated = false;
99   Handle(AIS_InteractiveObject) anAIS = 
100     theAIS ? theAIS->impl<Handle(AIS_InteractiveObject)>() : Handle(AIS_InteractiveObject)();
101   Handle(AIS_InteractiveContext) aContext = AISContext();
102   // Open local context if there is no one
103   if (!aContext->HasOpenedContext()) {
104     aContext->ClearCurrents(false);
105     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
106     // set mouse sensitivity
107     //aContext->SetSensitivityMode(StdSelect_SM_WINDOW);
108     //aContext->SetPixelTolerance(MOUSE_SENSITIVITY_IN_PIXEL);
109   }
110   // display or redisplay presentation
111   boost::shared_ptr<GeomAPI_AISObject> anObj = myFeature2AISObjectMap[theFeature];
112   if (isVisible(theFeature) && anObj && !anObj->empty()) {
113       aContext->RecomputeSelectionOnly(anAIS);
114   }
115   else {
116     myFeature2AISObjectMap[theFeature] = theAIS;
117     aContext->Display(anAIS, false);
118     isCreated = true;
119   }
120   if (isUpdateViewer)
121     updateViewer();
122
123   return isCreated;
124 }
125
126 bool XGUI_Displayer::redisplay(FeaturePtr theFeature, bool isUpdateViewer)
127 {
128   FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature);
129   if (!isVisible(aFeature))
130     return false;
131
132   boost::shared_ptr<GeomAPI_Shape> aShapePtr = aFeature->data()->shape();
133   if (aShapePtr) {
134     boost::shared_ptr<GeomAPI_AISObject> aAISObj = getAISObject(aFeature);
135     Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast(aAISObj->impl<Handle(AIS_InteractiveObject)>());
136     if (!aAISShape.IsNull()) {
137       aAISShape->Set(aShapePtr->impl<TopoDS_Shape>());
138       AISContext()->Redisplay(aAISShape);
139       return true;
140     }
141   }
142   return false;
143 }
144
145 void XGUI_Displayer::activateInLocalContext(FeaturePtr theFeature,
146                                          const std::list<int>& theModes, const bool isUpdateViewer)
147 {
148   Handle(AIS_InteractiveContext) aContext = AISContext();
149   // Open local context if there is no one
150   if (!aContext->HasOpenedContext()) {
151     aContext->ClearCurrents(false);
152     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
153   }
154   // display or redisplay presentation
155   Handle(AIS_InteractiveObject) anAIS;
156   if (isVisible(theFeature))
157   {
158     boost::shared_ptr<GeomAPI_AISObject> anObj = myFeature2AISObjectMap[theFeature];
159     if (anObj)
160       anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
161   }
162
163   // Activate selection of objects from prs
164   if (!anAIS.IsNull()) {
165     aContext->Load(anAIS, -1, true/*allow decomposition*/);
166     aContext->Deactivate(anAIS);
167
168     std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
169     for (; anIt != aLast; anIt++)
170     {
171       aContext->Activate(anAIS, (*anIt));
172     }
173   }
174
175   if (isUpdateViewer)
176     updateViewer();
177 }
178
179 void XGUI_Displayer::stopSelection(const QFeatureList& theFeatures, const bool isStop,
180                                    const bool isUpdateViewer)
181 {
182   Handle(AIS_InteractiveContext) aContext = AISContext();
183
184   Handle(AIS_Shape) anAIS;
185   QFeatureList::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
186   FeaturePtr aFeature;
187   for (; anIt != aLast; anIt++) {
188     aFeature = *anIt;
189     if (isVisible(aFeature))
190       anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
191     if (anAIS.IsNull())
192       continue;
193
194     if (isStop) {
195       QColor aColor(Qt::white);
196       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
197       anAIS->Redisplay();
198     }
199     else {
200       QColor aColor(Qt::red);
201       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
202       anAIS->Redisplay();
203     }
204   }
205   if (isUpdateViewer)
206     updateViewer();
207 }
208
209 void XGUI_Displayer::setSelected(const QFeatureList& theFeatures, const bool isUpdateViewer)
210 {
211   Handle(AIS_InteractiveContext) aContext = AISContext();
212   // we need to unhighligth objects manually in the current local context
213   // in couple with the selection clear (TODO)
214   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
215   if (!aLocalContext.IsNull())
216     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
217
218   aContext->ClearSelected();
219   foreach(FeaturePtr aFeature, theFeatures) {
220     FeaturePtr aRFeature = XGUI_Tools::realFeature(aFeature);
221     if (myFeature2AISObjectMap.find(aRFeature) == myFeature2AISObjectMap.end()) 
222       return;
223
224     boost::shared_ptr<GeomAPI_AISObject> anObj = myFeature2AISObjectMap[aRFeature];
225     if (anObj)
226     {
227       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
228       if (!anAIS.IsNull())
229         aContext->AddOrRemoveSelected(anAIS, false);
230     }
231   }
232   if (isUpdateViewer)
233     updateViewer();
234 }
235
236
237 /*void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
238 {
239   Handle(AIS_InteractiveContext) ic = AISContext();
240
241   AIS_ListOfInteractive aList;
242   ic->DisplayedObjects(aList);
243   AIS_ListIteratorOfListOfInteractive anIter(aList);
244   for (; anIter.More(); anIter.Next()) {
245     if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
246       continue;
247
248     // erase an object
249     Handle(AIS_InteractiveObject) anIO = anIter.Value();
250     ic->Erase(anIO, false);
251   }
252   myFeature2AISObjectMap.clear();
253   if (isUpdateViewer)
254     updateViewer();
255 }*/
256
257 void XGUI_Displayer::eraseDeletedFeatures(const bool isUpdateViewer)
258 {
259   Handle(AIS_InteractiveContext) aContext = AISContext();
260
261   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
262                                   aFLast = myFeature2AISObjectMap.end();
263   std::list<FeaturePtr> aRemoved;
264   for (; aFIt != aFLast; aFIt++)
265   {
266     FeaturePtr aFeature = (*aFIt).first;
267     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
268       boost::shared_ptr<GeomAPI_AISObject> anObj = (*aFIt).second;
269       if (!anObj) continue;
270       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
271       if (!anAIS.IsNull()) {
272         aContext->Erase(anAIS, false);
273         aRemoved.push_back(aFeature);
274       }
275     }
276   }
277   std::list<FeaturePtr>::const_iterator anIt = aRemoved.begin(),
278                                                                  aLast = aRemoved.end();
279   for (; anIt != aLast; anIt++) {
280     myFeature2AISObjectMap.erase(myFeature2AISObjectMap.find(*anIt));
281   }
282
283   if (isUpdateViewer)
284     updateViewer();
285 }
286
287 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
288 {
289   closeAllContexts(true);
290 }
291
292 boost::shared_ptr<GeomAPI_AISObject> XGUI_Displayer::getAISObject(
293                                               FeaturePtr theFeature) const
294 {
295   boost::shared_ptr<GeomAPI_AISObject> anIO;
296   if (myFeature2AISObjectMap.find(theFeature) != myFeature2AISObjectMap.end())
297     anIO = (myFeature2AISObjectMap.find(theFeature))->second;
298   return anIO;
299 }
300
301 FeaturePtr XGUI_Displayer::getFeature(Handle(AIS_InteractiveObject) theIO) const
302 {
303   FeaturePtr aFeature;
304   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
305                                   aFLast = myFeature2AISObjectMap.end();
306   for (; aFIt != aFLast && !aFeature; aFIt++) {
307     boost::shared_ptr<GeomAPI_AISObject> anObj = (*aFIt).second;
308     if (!anObj) continue;
309     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
310     if (anAIS != theIO)
311       continue;
312     aFeature = (*aFIt).first;
313   }
314   return aFeature;
315 }
316
317 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
318 {
319   Handle(AIS_InteractiveContext) ic = AISContext();
320   if (!ic.IsNull()) {
321     ic->CloseAllContexts(false);
322     if (isUpdateViewer)
323       updateViewer();
324   }
325 }
326
327 void XGUI_Displayer::updateViewer()
328 {
329   Handle(AIS_InteractiveContext) ic = AISContext();
330   if (!ic.IsNull())
331     ic->UpdateCurrentViewer();
332 }
333
334 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const 
335
336   return myWorkshop->viewer()->AISContext(); 
337 }