]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_Displayer.cpp
Salome HOME
8e0f38400d48cf1f6ece06010e3138a16ad6b881
[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
10 #include <ModelAPI_Document.h>
11 #include <ModelAPI_Data.h>
12 #include <ModelAPI_Object.h>
13 #include <ModelAPI_Tools.h>
14
15 #include <GeomAPI_Shape.h>
16 #include <GeomAPI_IPresentable.h>
17
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_LocalContext.hxx>
20 #include <AIS_ListOfInteractive.hxx>
21 #include <AIS_ListIteratorOfListOfInteractive.hxx>
22 #include <AIS_DimensionSelectionMode.hxx>
23 #include <AIS_Shape.hxx>
24 #include <AIS_Dimension.hxx>
25 #include <TColStd_ListIteratorOfListOfInteger.hxx>
26
27 #include <set>
28
29 const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse selection sensitivity
30
31 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
32 {
33   myWorkshop = theWorkshop;
34 }
35
36 XGUI_Displayer::~XGUI_Displayer()
37 {
38 }
39
40 bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
41 {
42   return myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end();
43 }
44
45 void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer)
46 {
47   if (isVisible(theObject)) {
48     redisplay(theObject, isUpdateViewer);
49   } else {
50     AISObjectPtr anAIS;
51
52     GeomPresentablePtr aPrs = boost::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
53     bool isShading = false;
54     if (aPrs) {
55       anAIS = aPrs->getAISObject(AISObjectPtr());
56     } else {
57       ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theObject);
58       if (aResult) {
59         boost::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
60         if (aShapePtr) {
61           anAIS = AISObjectPtr(new GeomAPI_AISObject());
62           anAIS->createShape(aShapePtr);
63           isShading = true;
64         }
65       }
66     }
67     if (anAIS)
68       display(theObject, anAIS, isShading, isUpdateViewer);
69   }
70 }
71
72 void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, 
73                              bool isShading, bool isUpdateViewer)
74 {
75   Handle(AIS_InteractiveContext) aContext = AISContext();
76   if (aContext.IsNull())
77     return;
78
79   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
80   if (!anAISIO.IsNull()) {
81     myResult2AISObjectMap[theObject] = theAIS;
82     aContext->Display(anAISIO, false);
83     aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, isUpdateViewer);
84   }
85 }
86
87 void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer)
88 {
89   if (!isVisible(theObject))
90     return;
91
92   Handle(AIS_InteractiveContext) aContext = AISContext();
93   if (aContext.IsNull())
94     return;
95   AISObjectPtr anObject = myResult2AISObjectMap[theObject];
96   if (anObject) {
97     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
98     if (!anAIS.IsNull()) {
99       aContext->Remove(anAIS, isUpdateViewer);
100     }
101   }
102   myResult2AISObjectMap.erase(theObject);
103 }
104
105 void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer)
106 {
107   if (!isVisible(theObject))
108     return;
109
110   Handle(AIS_InteractiveObject) aAISIO;
111   AISObjectPtr aAISObj = getAISObject(theObject);
112   GeomPresentablePtr aPrs = boost::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
113   if (aPrs) {
114     AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj);
115     if (aAISObj && !aAIS_Obj) {
116       erase(theObject, isUpdateViewer);
117       return;
118     }
119     aAISIO = aAIS_Obj->impl<Handle(AIS_InteractiveObject)>();
120   } else {
121     ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theObject);
122     if (aResult) {
123       boost::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
124       if (aShapePtr) {
125         Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast(
126             aAISObj->impl<Handle(AIS_InteractiveObject)>());
127         if (!aAISShape.IsNull()) {
128           aAISShape->Set(aShapePtr->impl<TopoDS_Shape>());
129           aAISIO = aAISShape;
130         }
131       }
132     }
133   }
134   if (!aAISIO.IsNull()) {
135     Handle(AIS_InteractiveContext) aContext = AISContext();
136     if (aContext.IsNull())
137       return;
138     aContext->Redisplay(aAISIO, isUpdateViewer);
139     //if (aContext->HasOpenedContext()) {
140     //  aContext->Load(aAISIO, -1, true/*allow decomposition*/);
141     //}
142   }
143 }
144
145 void XGUI_Displayer::deactivate(ObjectPtr theObject)
146 {
147   if (isVisible(theObject)) {
148     Handle(AIS_InteractiveContext) aContext = AISContext();
149     if (aContext.IsNull())
150       return;
151
152     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
153     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
154     aContext->Deactivate(anAIS);
155   }
156 }
157
158 void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes)
159 {
160   if (isVisible(theObject)) {
161     Handle(AIS_InteractiveContext) aContext = AISContext();
162     if (aContext.IsNull())
163       return;
164
165     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
166     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
167     if (aContext->HasOpenedContext()) {
168       aContext->Load(anAIS, -1, true);
169     }
170     if (theModes.size() > 0) {
171       foreach(int aMode, theModes) {
172         aContext->Activate(anAIS, aMode);
173       }
174     } else 
175       aContext->Activate(anAIS);
176   }
177 }
178
179 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
180 {
181   Handle(AIS_InteractiveContext) aContext = AISContext();
182   if (aContext.IsNull())
183     return false;
184   if (!isVisible(theObject))
185     return false;
186     
187   AISObjectPtr anObj = myResult2AISObjectMap.at(theObject);
188   Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
189
190   TColStd_ListOfInteger aModes;
191   aContext->ActivatedModes(anAIS, aModes);
192   return aModes.Extent() > 0;
193 }
194
195 void XGUI_Displayer::stopSelection(const QList<ObjectPtr>& theResults, const bool isStop,
196                                    const bool isUpdateViewer)
197 {
198   Handle(AIS_InteractiveContext) aContext = AISContext();
199   if (aContext.IsNull())
200     return;
201
202   Handle(AIS_Shape) anAIS;
203   QList<ObjectPtr>::const_iterator anIt = theResults.begin(), aLast = theResults.end();
204   ObjectPtr aFeature;
205   for (; anIt != aLast; anIt++) {
206     aFeature = *anIt;
207     if (isVisible(aFeature))
208       anAIS = Handle(AIS_Shape)::DownCast(
209           myResult2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
210     if (anAIS.IsNull())
211       continue;
212
213     if (isStop) {
214       QColor aColor(Qt::white);
215       anAIS->SetColor(
216           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
217                          Quantity_TOC_RGB));
218       anAIS->Redisplay();
219     } else {
220       QColor aColor(Qt::red);
221       anAIS->SetColor(
222           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
223                          Quantity_TOC_RGB));
224       anAIS->Redisplay();
225     }
226   }
227   if (isUpdateViewer)
228     updateViewer();
229 }
230
231 void XGUI_Displayer::setSelected(const QList<ObjectPtr>& theResults, const bool isUpdateViewer)
232 {
233   Handle(AIS_InteractiveContext) aContext = AISContext();
234   // we need to unhighligth objects manually in the current local context
235   // in couple with the selection clear (TODO)
236   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
237   if (!aLocalContext.IsNull())
238     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
239
240   aContext->ClearSelected();
241   foreach(ObjectPtr aResult, theResults)
242   {
243     if (myResult2AISObjectMap.find(aResult) == myResult2AISObjectMap.end())
244       continue;
245
246     AISObjectPtr anObj = myResult2AISObjectMap[aResult];
247     if (anObj) {
248       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
249       if (!anAIS.IsNull())
250         aContext->AddOrRemoveSelected(anAIS, false);
251     }
252   }
253   if (isUpdateViewer)
254     updateViewer();
255 }
256
257
258 void XGUI_Displayer::clearSelected()
259 {
260   Handle(AIS_InteractiveContext) aContext = AISContext();
261   if (aContext) {
262     aContext->UnhilightCurrents(false);
263     aContext->ClearSelected();
264   }
265 }
266
267 void XGUI_Displayer::eraseAll(const bool isUpdateViewer)
268 {
269   Handle(AIS_InteractiveContext) ic = AISContext();
270   if (ic.IsNull())
271     return;
272
273    ResultToAISMap::iterator aIt;
274    for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) {
275      // erase an object
276      AISObjectPtr aAISObj = (*aIt).second;
277      Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
278      if (!anIO.IsNull())
279       ic->Remove(anIO, false);
280    }
281    myResult2AISObjectMap.clear();
282    if (isUpdateViewer)
283      updateViewer();
284  }
285
286 void XGUI_Displayer::eraseDeletedResults(const bool isUpdateViewer)
287 {
288   Handle(AIS_InteractiveContext) aContext = AISContext();
289   if (aContext.IsNull())
290     return;
291
292   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
293       myResult2AISObjectMap.end();
294   std::list<ObjectPtr> aRemoved;
295   for (; aFIt != aFLast; aFIt++) {
296     ObjectPtr aFeature = (*aFIt).first;
297     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
298       AISObjectPtr anObj = (*aFIt).second;
299       if (!anObj)
300         continue;
301       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
302       if (!anAIS.IsNull()) {
303         aContext->Remove(anAIS, false);
304         aRemoved.push_back(aFeature);
305       }
306     }
307   }
308   std::list<ObjectPtr>::const_iterator anIt = aRemoved.begin(), aLast = aRemoved.end();
309   for (; anIt != aLast; anIt++) {
310     myResult2AISObjectMap.erase(myResult2AISObjectMap.find(*anIt));
311   }
312
313   if (isUpdateViewer)
314     updateViewer();
315 }
316
317 void XGUI_Displayer::openLocalContext()
318 {
319   Handle(AIS_InteractiveContext) aContext = AISContext();
320   if (aContext.IsNull())
321     return;
322   // Open local context if there is no one
323   if (!aContext->HasOpenedContext()) {
324     aContext->ClearCurrents(false);
325     //aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
326     aContext->OpenLocalContext();
327     aContext->NotUseDisplayedObjects();
328   }
329 }
330
331 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
332 {
333   AISContext()->ClearSelected(false);
334   closeAllContexts(true);
335 }
336
337 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
338 {
339   AISObjectPtr anIO;
340   if (myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end())
341     anIO = (myResult2AISObjectMap.find(theObject))->second;
342   return anIO;
343 }
344
345 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
346 {
347   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
348   return getObject(aRefAIS);
349 }
350
351 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
352 {
353   ObjectPtr aFeature;
354   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
355       myResult2AISObjectMap.end();
356   for (; aFIt != aFLast && !aFeature; aFIt++) {
357     AISObjectPtr anObj = (*aFIt).second;
358     if (!anObj)
359       continue;
360     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
361     if (anAIS != theIO)
362       continue;
363     aFeature = (*aFIt).first;
364   }
365   return aFeature;
366 }
367
368 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
369 {
370   Handle(AIS_InteractiveContext) ic = AISContext();
371   if (!ic.IsNull()) {
372     ic->CloseAllContexts(false);
373     if (isUpdateViewer)
374       updateViewer();
375   }
376 }
377
378 void XGUI_Displayer::updateViewer()
379 {
380   Handle(AIS_InteractiveContext) ic = AISContext();
381   if (!ic.IsNull())
382     ic->UpdateCurrentViewer();
383 }
384
385 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
386 {
387   return myWorkshop->viewer()->AISContext();
388 }
389
390 void XGUI_Displayer::display(AISObjectPtr theAIS, bool isUpdate)
391 {
392   Handle(AIS_InteractiveContext) aContext = AISContext();
393   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
394   if (!anAISIO.IsNull())
395     aContext->Display(anAISIO, isUpdate);
396 }
397
398 void XGUI_Displayer::erase(AISObjectPtr theAIS, const bool isUpdate)
399 {
400   Handle(AIS_InteractiveContext) aContext = AISContext();
401   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
402   if (!anAISIO.IsNull()) {
403     aContext->Remove(anAISIO, isUpdate);
404   }
405 }
406
407 void XGUI_Displayer::activateObjectsOutOfContext(const QIntList& theModes)
408 {
409   Handle(AIS_InteractiveContext) aContext = AISContext();
410   // Open local context if there is no one
411   if (!aContext->HasOpenedContext()) 
412     return;
413
414   aContext->UseDisplayedObjects();
415   ResultToAISMap::iterator aIt;
416   Handle(AIS_InteractiveObject) anAISIO;
417   for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) {
418     anAISIO = (*aIt).second->impl<Handle(AIS_InteractiveObject)>();
419     aContext->Load(anAISIO, -1, true);
420     if (theModes.size() == 0)
421       aContext->Activate(anAISIO);
422     else {
423       foreach(int aMode, theModes) {
424         aContext->Activate(anAISIO, aMode);
425       }
426     }
427   }
428 }
429
430
431 void XGUI_Displayer::deactivateObjectsOutOfContext()
432 {
433   Handle(AIS_InteractiveContext) aContext = AISContext();
434   // Open local context if there is no one
435   if (!aContext->HasOpenedContext()) 
436     return;
437
438   aContext->NotUseDisplayedObjects();
439 }
440
441
442 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
443 {
444   if (theMode == NoMode)
445     return;
446
447   Handle(AIS_InteractiveContext) aContext = AISContext();
448   if (aContext.IsNull())
449     return;
450
451   AISObjectPtr aAISObj = getAISObject(theObject);
452   if (!aAISObj)
453     return;
454
455   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
456   aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
457 }
458
459 void XGUI_Displayer::setSelectionModes(const QIntList& theModes)
460 {
461   Handle(AIS_InteractiveContext) aContext = AISContext();
462   if (aContext.IsNull())
463     return;
464   if (!aContext->HasOpenedContext())
465     return;
466   // Clear previous mode
467   const TColStd_ListOfInteger& aModes = aContext->ActivatedStandardModes();
468   if (!aModes.IsEmpty()) {
469     TColStd_ListOfInteger aMModes;
470     aMModes.Assign(aModes);
471     TColStd_ListIteratorOfListOfInteger it(aMModes);
472     for(; it.More(); it.Next()) {
473       aContext->DeactivateStandardMode((TopAbs_ShapeEnum)it.Value());
474     }
475   }
476   foreach(int aMode, theModes) {
477     aContext->ActivateStandardMode((TopAbs_ShapeEnum)aMode);
478   }
479 }
480
481 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
482 {
483   Handle(AIS_InteractiveContext) aContext = AISContext();
484   if (aContext.IsNull())
485     return NoMode;
486
487   AISObjectPtr aAISObj = getAISObject(theObject);
488   if (!aAISObj)
489     return NoMode;
490
491   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
492   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
493 }
494
495 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
496 {
497   Handle(AIS_InteractiveContext) aContext = AISContext();
498   if (aContext.IsNull())
499     return;
500   aContext->AddFilter(theFilter);
501 }
502
503 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
504 {
505   Handle(AIS_InteractiveContext) aContext = AISContext();
506   if (aContext.IsNull())
507     return;
508   aContext->RemoveFilter(theFilter);
509 }