Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into SketchSolver
[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 void 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     display(aFeature, anAIS, isUpdateViewer);
53   }
54 }
55
56 void XGUI_Displayer::display(FeaturePtr theFeature,
57                              boost::shared_ptr<GeomAPI_AISObject> theAIS, bool isUpdateViewer)
58 {
59   Handle(AIS_InteractiveContext) aContext = AISContext();
60
61   myFeature2AISObjectMap[theFeature] = theAIS;
62
63   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
64   if (!anAISIO.IsNull())
65     aContext->Display(anAISIO, isUpdateViewer);
66 }
67
68
69 std::list<XGUI_ViewerPrs> XGUI_Displayer::getSelected(const int theShapeTypeToSkip)
70 {
71   std::set<FeaturePtr > aPrsFeatures;
72   std::list<XGUI_ViewerPrs> aPresentations;
73
74   Handle(AIS_InteractiveContext) aContext = AISContext();
75   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
76     Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
77     TopoDS_Shape aShape = aContext->SelectedShape();
78
79     if (theShapeTypeToSkip >= 0 && !aShape.IsNull() && aShape.ShapeType() == theShapeTypeToSkip)
80       continue;
81
82     FeaturePtr aFeature = getFeature(anIO);
83     if (aPrsFeatures.find(aFeature) != aPrsFeatures.end())
84       continue;
85     Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
86     aPresentations.push_back(XGUI_ViewerPrs(aFeature, aShape, anOwner));
87     aPrsFeatures.insert(aFeature);
88   }
89   return aPresentations;
90 }
91
92 QFeatureList XGUI_Displayer::selectedFeatures() const
93 {
94   QFeatureList aSelectedList;
95
96   Handle(AIS_InteractiveContext) aContext = AISContext();
97   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
98     Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
99     FeaturePtr aFeature = getFeature(anIO);
100     if (aFeature)
101       aSelectedList.append(aFeature);
102   }
103   return aSelectedList;
104 }
105
106
107 std::list<XGUI_ViewerPrs> XGUI_Displayer::getHighlighted(const int theShapeTypeToSkip)
108 {
109   std::set<FeaturePtr > aPrsFeatures;
110   std::list<XGUI_ViewerPrs> aPresentations;
111
112   Handle(AIS_InteractiveContext) aContext = AISContext();
113   for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) {
114     Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive();
115     TopoDS_Shape aShape = aContext->DetectedShape();
116     if (theShapeTypeToSkip >= 0 && !aShape.IsNull() && aShape.ShapeType() == theShapeTypeToSkip)
117       continue;
118
119     FeaturePtr aFeature = getFeature(anIO);
120     if (aPrsFeatures.find(aFeature) != aPrsFeatures.end())
121       continue;
122     aPresentations.push_back(XGUI_ViewerPrs(aFeature, aShape, NULL));
123     aPrsFeatures.insert(aFeature);
124   }
125
126   return aPresentations;
127 }
128
129 void XGUI_Displayer::erase(FeaturePtr theFeature,
130                            const bool isUpdateViewer)
131 {
132   FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature);
133
134   if (myFeature2AISObjectMap.find(aFeature) == myFeature2AISObjectMap.end())
135     return;
136
137   Handle(AIS_InteractiveContext) aContext = AISContext();
138   boost::shared_ptr<GeomAPI_AISObject> anObject = myFeature2AISObjectMap[aFeature];
139   if (anObject)
140   {
141     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
142     if (!anAIS.IsNull())
143       aContext->Erase(anAIS, isUpdateViewer);
144   }
145   myFeature2AISObjectMap.erase(aFeature);
146 }
147
148
149 bool XGUI_Displayer::redisplay(FeaturePtr theFeature,
150                                boost::shared_ptr<GeomAPI_AISObject> theAIS,
151                                const bool isUpdateViewer)
152 {
153   bool isCreated = false;
154   Handle(AIS_InteractiveObject) anAIS = 
155     theAIS ? theAIS->impl<Handle(AIS_InteractiveObject)>() : Handle(AIS_InteractiveObject)();
156   Handle(AIS_InteractiveContext) aContext = AISContext();
157   // Open local context if there is no one
158   if (!aContext->HasOpenedContext()) {
159     aContext->ClearCurrents(false);
160     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
161     // set mouse sensitivity
162     //aContext->SetSensitivityMode(StdSelect_SM_WINDOW);
163     //aContext->SetPixelTolerance(MOUSE_SENSITIVITY_IN_PIXEL);
164   }
165   // display or redisplay presentation
166   boost::shared_ptr<GeomAPI_AISObject> anObj = myFeature2AISObjectMap[theFeature];
167   if (isVisible(theFeature) && anObj && !anObj->empty()) {
168       aContext->RecomputeSelectionOnly(anAIS);
169   }
170   else {
171     myFeature2AISObjectMap[theFeature] = theAIS;
172     aContext->Display(anAIS, false);
173     isCreated = true;
174   }
175   if (isUpdateViewer)
176     updateViewer();
177
178   return isCreated;
179 }
180
181 void XGUI_Displayer::redisplay(FeaturePtr theFeature, bool isUpdateViewer)
182 {
183   FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature);
184   if (!isVisible(aFeature))
185     return;
186
187   boost::shared_ptr<GeomAPI_Shape> aShapePtr = aFeature->data()->shape();
188   if (aShapePtr) {
189     boost::shared_ptr<GeomAPI_AISObject> aAISObj = getAISObject(aFeature);
190     Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast(aAISObj->impl<Handle(AIS_InteractiveObject)>());
191     if (!aAISShape.IsNull())
192       return;
193
194     aAISShape->Set(aShapePtr->impl<TopoDS_Shape>());
195     AISContext()->Redisplay(aAISShape);
196   }
197 }
198
199 void XGUI_Displayer::activateInLocalContext(FeaturePtr theFeature,
200                                          const std::list<int>& theModes, const bool isUpdateViewer)
201 {
202   Handle(AIS_InteractiveContext) aContext = AISContext();
203   // Open local context if there is no one
204   if (!aContext->HasOpenedContext()) {
205     aContext->ClearCurrents(false);
206     aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
207   }
208   // display or redisplay presentation
209   Handle(AIS_InteractiveObject) anAIS;
210   if (isVisible(theFeature))
211   {
212     boost::shared_ptr<GeomAPI_AISObject> anObj = myFeature2AISObjectMap[theFeature];
213     if (anObj)
214       anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
215   }
216
217   // Activate selection of objects from prs
218   if (!anAIS.IsNull()) {
219     aContext->Load(anAIS, -1, true/*allow decomposition*/);
220     aContext->Deactivate(anAIS);
221
222     std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
223     for (; anIt != aLast; anIt++)
224     {
225       aContext->Activate(anAIS, (*anIt));
226     }
227   }
228
229   if (isUpdateViewer)
230     updateViewer();
231 }
232
233 void XGUI_Displayer::stopSelection(const QFeatureList& theFeatures, const bool isStop,
234                                    const bool isUpdateViewer)
235 {
236   Handle(AIS_InteractiveContext) aContext = AISContext();
237
238   Handle(AIS_Shape) anAIS;
239   QFeatureList::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
240   FeaturePtr aFeature;
241   for (; anIt != aLast; anIt++) {
242     aFeature = *anIt;
243     if (isVisible(aFeature))
244       anAIS = Handle(AIS_Shape)::DownCast(myFeature2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
245     if (anAIS.IsNull())
246       continue;
247
248     if (isStop) {
249       QColor aColor(Qt::white);
250       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
251       anAIS->Redisplay();
252     }
253     else {
254       QColor aColor(Qt::red);
255       anAIS->SetColor(Quantity_Color(aColor.red()/255., aColor.green()/255., aColor.blue()/255., Quantity_TOC_RGB));
256       anAIS->Redisplay();
257     }
258   }
259   if (isUpdateViewer)
260     updateViewer();
261 }
262
263 void XGUI_Displayer::setSelected(const QFeatureList& theFeatures, const bool isUpdateViewer)
264 {
265   Handle(AIS_InteractiveContext) aContext = AISContext();
266   // we need to unhighligth objects manually in the current local context
267   // in couple with the selection clear (TODO)
268   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
269   if (!aLocalContext.IsNull())
270     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
271
272   aContext->ClearSelected();
273   foreach(FeaturePtr aFeature, theFeatures) {
274     FeaturePtr aRFeature = XGUI_Tools::realFeature(aFeature);
275     if (myFeature2AISObjectMap.find(aRFeature) == myFeature2AISObjectMap.end()) 
276       return;
277
278     boost::shared_ptr<GeomAPI_AISObject> anObj = myFeature2AISObjectMap[aRFeature];
279     if (anObj)
280     {
281       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
282       if (!anAIS.IsNull())
283         aContext->AddOrRemoveSelected(anAIS, false);
284     }
285   }
286   if (isUpdateViewer)
287     updateViewer();
288 }
289
290
291 /*void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
292 {
293   Handle(AIS_InteractiveContext) ic = AISContext();
294
295   AIS_ListOfInteractive aList;
296   ic->DisplayedObjects(aList);
297   AIS_ListIteratorOfListOfInteractive anIter(aList);
298   for (; anIter.More(); anIter.Next()) {
299     if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
300       continue;
301
302     // erase an object
303     Handle(AIS_InteractiveObject) anIO = anIter.Value();
304     ic->Erase(anIO, false);
305   }
306   myFeature2AISObjectMap.clear();
307   if (isUpdateViewer)
308     updateViewer();
309 }*/
310
311 void XGUI_Displayer::eraseDeletedFeatures(const bool isUpdateViewer)
312 {
313   Handle(AIS_InteractiveContext) aContext = AISContext();
314
315   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
316                                   aFLast = myFeature2AISObjectMap.end();
317   std::list<FeaturePtr> aRemoved;
318   for (; aFIt != aFLast; aFIt++)
319   {
320     FeaturePtr aFeature = (*aFIt).first;
321     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
322       boost::shared_ptr<GeomAPI_AISObject> anObj = (*aFIt).second;
323       if (!anObj) continue;
324       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
325       if (!anAIS.IsNull()) {
326         aContext->Erase(anAIS, false);
327         aRemoved.push_back(aFeature);
328       }
329     }
330   }
331   std::list<FeaturePtr>::const_iterator anIt = aRemoved.begin(),
332                                                                  aLast = aRemoved.end();
333   for (; anIt != aLast; anIt++) {
334     myFeature2AISObjectMap.erase(myFeature2AISObjectMap.find(*anIt));
335   }
336
337   if (isUpdateViewer)
338     updateViewer();
339 }
340
341 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
342 {
343   closeAllContexts(true);
344 }
345
346 boost::shared_ptr<GeomAPI_AISObject> XGUI_Displayer::getAISObject(
347                                               FeaturePtr theFeature) const
348 {
349   boost::shared_ptr<GeomAPI_AISObject> anIO;
350   if (myFeature2AISObjectMap.find(theFeature) != myFeature2AISObjectMap.end())
351     anIO = (myFeature2AISObjectMap.find(theFeature))->second;
352   return anIO;
353 }
354
355 FeaturePtr XGUI_Displayer::getFeature(Handle(AIS_InteractiveObject) theIO) const
356 {
357   FeaturePtr aFeature;
358   FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(),
359                                   aFLast = myFeature2AISObjectMap.end();
360   for (; aFIt != aFLast && !aFeature; aFIt++) {
361     boost::shared_ptr<GeomAPI_AISObject> anObj = (*aFIt).second;
362     if (!anObj) continue;
363     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
364     if (anAIS != theIO)
365       continue;
366     aFeature = (*aFIt).first;
367   }
368   return aFeature;
369 }
370
371 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
372 {
373   Handle(AIS_InteractiveContext) ic = AISContext();
374   if (!ic.IsNull()) {
375     ic->CloseAllContexts(false);
376     if (isUpdateViewer)
377       updateViewer();
378   }
379 }
380
381 void XGUI_Displayer::updateViewer()
382 {
383   Handle(AIS_InteractiveContext) ic = AISContext();
384   if (!ic.IsNull())
385     ic->UpdateCurrentViewer();
386 }
387
388 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const 
389
390   return myWorkshop->viewer()->AISContext(); 
391 }