Salome HOME
Porting to OCCT 7.4.1dev
[modules/gui.git] / src / SOCC / SOCC_ViewModel.cxx
1 // Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "SOCC_ViewModel.h"
24
25 #include "SOCC_Prs.h"
26 #include "SOCC_ViewWindow.h"
27
28 #include "SUIT_Session.h"
29 #include "SUIT_ResourceMgr.h"
30 //#include "SUIT_Application.h"
31
32 //#include "ToolsGUI.h"
33
34 // Temporarily commented to avoid awful dependecy on SALOMEDS
35 // TODO: better mechanism of storing display/erse status in a study
36 // should be provided...
37 //#include <SALOMEconfig.h>
38 //#include CORBA_CLIENT_HEADER(SALOMEDS)
39
40 #include <AIS_ListIteratorOfListOfInteractive.hxx>
41
42 #include <SALOME_AISShape.hxx>
43 #include <SALOME_AISObject.hxx>
44 #include <SALOME_InteractiveObject.hxx>
45 #include <SALOME_ListIO.hxx>
46
47 #include <AIS_TypeOfIso.hxx>
48 #include <Precision.hxx>
49
50 #include <algorithm>
51
52 /*!
53   Constructor
54   \param DisplayTrihedron - is trihedron displayed
55 */
56 SOCC_Viewer::SOCC_Viewer( bool DisplayTrihedron )
57 : OCCViewer_Viewer( DisplayTrihedron )
58 {
59 }
60
61 /*!
62   Destructor
63 */
64 SOCC_Viewer::~SOCC_Viewer()
65 {
66 }
67
68 /*!
69   Hilights/unhilights object in viewer
70   \param obj - object to be updated
71   \param hilight - if it is true, object will be hilighted, otherwise it will be unhilighted
72   \param update - update current viewer
73 */
74 bool SOCC_Viewer::highlight( const Handle(SALOME_InteractiveObject)& obj,
75                              bool hilight, bool upd )
76 {
77   AIS_ListOfInteractive List;
78   getAISContext()->DisplayedObjects(List);
79   
80   AIS_ListIteratorOfListOfInteractive ite(List);
81   for ( ; ite.More(); ite.Next() )
82   {
83     Handle(SALOME_InteractiveObject) anObj =
84       Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
85
86     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
87     {
88       OCCViewer_Viewer::highlight( ite.Value(), hilight, false );
89       // highlight sub-shapes only when local selection is active
90       break;
91     }
92   }
93     
94   if( upd )
95     update();
96     
97   return false;
98 }
99
100 /*!
101   \return true if object is in viewer or in collector
102   \param obj - object to be checked
103   \param onlyInViewer - search object only in viewer (so object must be displayed)
104 */
105 bool SOCC_Viewer::isInViewer( const Handle(SALOME_InteractiveObject)& obj,
106                               bool onlyInViewer )
107 {
108   AIS_ListOfInteractive List;
109   getAISContext()->DisplayedObjects(List);
110   AIS_ListIteratorOfListOfInteractive ite(List);
111   for ( ; ite.More(); ite.Next() )
112   {
113     Handle(SALOME_InteractiveObject) anObj =
114         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
115
116     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
117       return true;
118   }
119   return false;
120 }
121
122 /*!
123   \return true if object is displayed in viewer
124   \param obj - object to be checked
125 */
126 bool SOCC_Viewer::isVisible( const Handle(SALOME_InteractiveObject)& obj )
127 {
128
129   std::map< std::string , std::vector<Handle(AIS_InteractiveObject)> >::iterator it=entry2aisobjects.find(obj->getEntry());
130   if(it != entry2aisobjects.end())
131     {
132       // get context
133       Handle (AIS_InteractiveContext) ic = getAISContext();
134       std::vector<Handle(AIS_InteractiveObject)>& List = it->second;
135       for( unsigned int ind = 0; ind < List.size(); ind++ )
136         {
137           Handle(AIS_InteractiveObject) anAIS=List[ind];
138           if(ic->IsDisplayed(anAIS))
139             return true;
140         }
141   }
142   
143   return false;
144 }
145
146 /*!
147   Sets color of object
148   \param obj - object to be updated
149   \param color - new color
150   \param update - update current viewer
151 */
152 void SOCC_Viewer::setColor( const Handle(SALOME_InteractiveObject)& obj,
153                             const QColor& color, bool update )
154 {
155   if(obj.IsNull() || !obj->hasEntry() )
156     return;
157
158   if(entry2aisobjects.count(obj->getEntry())>0)
159     {
160       // get context
161       Handle (AIS_InteractiveContext) ic = getAISContext();
162       std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[obj->getEntry()];
163       for( unsigned int ind = 0; ind < List.size(); ind++ )
164         {
165           Handle(AIS_InteractiveObject) anAIS=List[ind];
166           if( !anAIS.IsNull() && ic->IsDisplayed(anAIS))
167             OCCViewer_Viewer::setColor( anAIS, color, update );
168         }
169     }
170 }
171
172 /*!
173   Changes display mode of object
174   \param obj - object to be processed
175   \param mode - new display mode
176   \param update - update current viewer
177 */
178 void SOCC_Viewer::switchRepresentation( const Handle(SALOME_InteractiveObject)& obj,
179                                         int mode, bool update )
180 {
181   if(obj.IsNull() || !obj->hasEntry() )
182     return;
183
184   if(entry2aisobjects.count(obj->getEntry())>0)
185     {
186       // get context
187       Handle (AIS_InteractiveContext) ic = getAISContext();
188       std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[obj->getEntry()];
189       for( unsigned int ind = 0; ind < List.size(); ind++ )
190         {
191           Handle(AIS_InteractiveObject) anAIS=List[ind];
192           if( !anAIS.IsNull() && ic->IsDisplayed(anAIS))
193             OCCViewer_Viewer::switchRepresentation( anAIS, mode, update );
194         }
195     }
196 }
197
198 /*!
199   Changes transparency of object
200   \param obj - object to be processed
201   \param trans - new transparency
202   \param update - update current viewer
203 */
204 void SOCC_Viewer::setTransparency( const Handle(SALOME_InteractiveObject)& obj,
205                                    float trans, bool update )
206 {
207   if(obj.IsNull() || !obj->hasEntry() )
208     return;
209
210   if(entry2aisobjects.count(obj->getEntry())>0)
211     {
212       // get context
213       Handle (AIS_InteractiveContext) ic = getAISContext();
214       std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[obj->getEntry()];
215       for( unsigned int ind = 0; ind < List.size(); ind++ )
216         {
217           Handle(AIS_InteractiveObject) anAIS=List[ind];
218           if( !anAIS.IsNull() && ic->IsDisplayed(anAIS))
219             OCCViewer_Viewer::setTransparency( anAIS, trans, update );
220         }
221     }
222 }
223
224 /*!
225   Changes name of object
226   \param obj - object to be renamed
227   \param name - new name
228 */
229 void SOCC_Viewer::rename( const Handle(SALOME_InteractiveObject)& obj,
230                           const QString& name )
231 {
232   AIS_ListOfInteractive List;
233   getAISContext()->DisplayedObjects(List);
234   
235   AIS_ListIteratorOfListOfInteractive ite(List);
236   while (ite.More())
237   {
238     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape)))
239     {
240       Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast(ite.Value());
241       
242       if ( aSh->hasIO() )
243       {
244         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
245         if ( IO->isSame( obj ) )
246         {
247           aSh->setName( name.toUtf8().data() );
248           break;
249         }
250       }
251     }
252     else if ( ite.Value()->IsKind( STANDARD_TYPE( SALOME_AISObject ) ) )
253     {
254       Handle(SALOME_AISObject) aSh = Handle(SALOME_AISObject)::DownCast( ite.Value() );
255
256       // Add code here, if someone create a MODULE_AISObject.
257     }
258     ite.Next();
259   }
260 }
261
262
263 /*!
264   Display presentation
265   \param prs - presentation
266 */
267 void SOCC_Viewer::Display( const SALOME_OCCPrs* prs )
268 {
269   // try do downcast object
270   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( prs );
271   if ( !anOCCPrs || anOCCPrs->IsNull() )
272     return;
273
274   // get context
275   Handle (AIS_InteractiveContext) ic = getAISContext();
276
277   // get objects to be displayed
278   AIS_ListOfInteractive anAISObjects;
279   anOCCPrs->GetObjects( anAISObjects );
280
281   AIS_ListIteratorOfListOfInteractive aIter( anAISObjects );
282   for ( ; aIter.More(); aIter.Next() )
283   {
284     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
285     if ( !anAIS.IsNull() )
286     {
287       // try to find presentation in the viewer
288
289       // if the object is already displayed - nothing to do more
290       if(ic->IsDisplayed(anAIS))
291         {
292           // Deactivate object if necessary
293           if ( !anOCCPrs->ToActivate() )
294             ic->Deactivate( anAIS );
295           continue;
296         }
297
298       // if object is not displayed and not found in the collector - display it
299       if ( anAIS->IsKind( STANDARD_TYPE(AIS_Trihedron) ) )
300       {
301         Handle(AIS_Trihedron) aTrh = Handle(AIS_Trihedron)::DownCast( anAIS );
302         double aNewSize = 100, aSize = 100;
303         computeTrihedronSize( aNewSize, aSize );
304         aTrh->SetSize( aTrh == getTrihedron() ? aNewSize : 0.5 * aNewSize );
305       }
306
307       ic->Display( anAIS, false );
308       Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast (anAIS);
309       if (!aSh.IsNull())
310       {
311         aSh->SetClippable (prs->IsClippable());
312         applyExistingClipPlanesToObject (anAIS);
313         bool top = (aSh->isTopLevel() && aSh->switchTopLevel());
314               ic->SetZLayer( aSh, top ? getTopLayerId() : 0 );
315                     if(!aSh->toActivate())
316         {
317                             ic->Deactivate( aSh );
318                     }
319       }
320
321       //Register anAIS (if it has an entry) in entry2aisobjects map
322       Handle(SALOME_InteractiveObject) anObj = Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
323       if ( !anObj.IsNull() && anObj->hasEntry())
324         {
325           std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[anObj->getEntry()];
326           int found=0;
327           for ( unsigned int ind = 0; ind < List.size(); ind++ )
328           {
329             if(List[ind] == anAIS)
330               {
331                 found=1;
332                 break;
333               }
334           }
335           if(!found)
336             {
337               List.push_back(anAIS);
338             }
339         }
340
341       // Set visibility flag
342       // Temporarily commented to avoid awful dependecy on SALOMEDS
343       // TODO: better mechanism of storing display/erse status in a study
344       // should be provided...
345       //Handle(SALOME_InteractiveObject) anObj =
346       //  Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
347       //if ( !anObj.IsNull() && anObj->hasEntry() )
348       //{
349       //  ToolsGUI::SetVisibility( anObj->getEntry(), true, this );
350       //}
351
352       // Deactivate object if necessary
353       if ( !anOCCPrs->ToActivate() )
354         ic->Deactivate( anAIS );
355     }
356   }
357   updateTrihedron();
358 }
359
360
361 /*!
362   Erase presentation
363   \param prs - presentation
364   \param forced - removes object from context
365 */
366 void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced )
367 {
368   // try do downcast object
369   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( prs );
370   if ( !anOCCPrs || anOCCPrs->IsNull() )
371     return;
372
373   // get context
374   Handle(AIS_InteractiveContext) ic = getAISContext();
375
376   // get objects to be erased
377   AIS_ListOfInteractive anAISObjects;
378   anOCCPrs->GetObjects( anAISObjects );
379
380   AIS_ListIteratorOfListOfInteractive aIter( anAISObjects );
381   for ( ; aIter.More(); aIter.Next() ) {
382     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
383     if ( !anAIS.IsNull() ) {
384       // erase the object from context : move it to collector
385       ic->Erase( anAIS, false );
386       // Set visibility flag if necessary
387       // Temporarily commented to avoid awful dependecy on SALOMEDS
388       // TODO: better mechanism of storing display/erse status in a study
389       // should be provided...
390       //if ( !forced )
391       //{
392       //  Handle(SALOME_InteractiveObject) anObj =
393       //    Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
394       //  if ( !anObj.IsNull() && anObj->hasEntry() )
395       //  {
396       //    ToolsGUI::SetVisibility( anObj->getEntry(), true, this );
397       //  }
398       //}
399     }
400   }
401   updateTrihedron();
402 }
403
404
405 /*!
406   Erase all presentations
407   \param forced - removes all objects from context
408 */
409 void SOCC_Viewer::EraseAll( SALOME_Displayer* d, const bool forced )
410 {
411   // get context
412   Handle(AIS_InteractiveContext) ic = getAISContext();
413
414   // check if trihedron is displayed
415   Standard_Boolean isTrihedronDisplayed = ic->IsDisplayed( getTrihedron() );
416
417   // get objects to be erased (all currently displayed objects)
418   AIS_ListOfInteractive aList;
419   ic->DisplayedObjects( aList );
420   AIS_ListIteratorOfListOfInteractive anIter( aList );
421   for ( ; anIter.More(); anIter.Next() ) {
422     if ( (isTrihedronDisplayed && anIter.Value()->DynamicType() == STANDARD_TYPE( AIS_Trihedron ) ) )
423       continue;
424
425     // erase an object
426     Handle(AIS_InteractiveObject) anIO = anIter.Value();
427     ic->Erase( anIO, false );
428     
429     // Set visibility flag if necessary
430     // Temporarily commented to avoid awful dependecy on SALOMEDS
431     // TODO: better mechanism of storing display/erse status in a study
432     // should be provided...
433     //if ( !forced ) {
434     //  Handle(SALOME_InteractiveObject) anObj =
435     //  Handle(SALOME_InteractiveObject)::DownCast( anIO->GetOwner() );
436
437     //  if ( !anObj.IsNull() && anObj->hasEntry() ) {
438     //    ToolsGUI::SetVisibility( anObj->getEntry(), true, this );
439     //  }
440     //}
441   }
442
443   SALOME_View::EraseAll( d, forced );
444
445   Repaint();
446   updateTrihedron();
447 }
448
449 /*!
450   Create presentation corresponding to the entry
451   \param entry - entry
452 */
453 SALOME_Prs* SOCC_Viewer::CreatePrs( const char* entry )
454 {
455   SOCC_Prs* prs = new SOCC_Prs(entry);
456   if ( entry )
457   {
458     if(entry2aisobjects.count(entry)>0)
459       {
460         //ais object exists
461         std::vector<Handle(AIS_InteractiveObject)> List = entry2aisobjects[entry];
462         // get context
463         Handle(AIS_InteractiveContext) ic = getAISContext();
464         //add all ais
465         for ( unsigned int ind = 0; ind < List.size(); ind++ )
466           {
467             Handle(AIS_InteractiveObject) anAIS=List[ind];
468             if(ic->IsDisplayed(anAIS))
469               {
470                 prs->AddObject( anAIS );
471               }
472           }
473       }
474   }
475   return prs;
476 }
477
478 /*!
479   Activates selection of sub-shapes
480 */
481 void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const std::list<int> modes )
482 {
483   Handle(AIS_InteractiveContext) ic = getAISContext();
484   
485   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( thePrs );
486   if ( ic.IsNull() )
487     return;
488   
489   // Open local context if there is no one
490   bool allObjects = thePrs == 0 || thePrs->IsNull();
491   ic->Deactivate();
492
493   AIS_ListOfInteractive anObjs;
494   // Get objects to be activated
495   if ( allObjects ) 
496     ic->DisplayedObjects( anObjs );
497   else
498     anOCCPrs->GetObjects( anObjs );
499
500   std::list<int> sel_modes;
501   for ( int i = TopAbs_COMPOUND; i < TopAbs_SHAPE; i++ )
502     if ( std::find(modes.begin(), modes.end(), (int)TopAbs_SHAPE) != modes.end() || std::find(modes.begin(), modes.end(), i) != modes.end())
503       sel_modes.push_back(i);
504
505   // Activate selection of objects from prs
506   AIS_ListIteratorOfListOfInteractive aIter( anObjs );
507   for ( ; aIter.More(); aIter.Next() ) {
508     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
509     if ( !anAIS.IsNull() )
510     {
511       std::list<int>::const_iterator it;
512       if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
513       {
514         ic->Load( anAIS, -1, false );
515         for( it = sel_modes.begin(); it != sel_modes.end(); ++it )
516           ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)*it ) );
517       }
518       else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
519       {
520         ic->Load( anAIS, -1, false );
521         for( it = sel_modes.begin(); it != sel_modes.end(); ++it )
522           ic->Activate( anAIS, *it );
523       }
524     }
525   }
526 }
527
528 /*!
529   Activates selection of sub-shapes
530 */
531 void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const int theMode )
532 {
533   std::list<int> modes;
534   modes.push_back( theMode );
535   LocalSelection( thePrs, modes );
536 }
537
538 /*!
539   Deactivates selection of sub-shapes
540 */
541 void SOCC_Viewer::GlobalSelection( const bool update ) const
542 {
543   Handle(AIS_InteractiveContext) ic = getAISContext();
544   if ( !ic.IsNull() )
545   {
546     ic->Deactivate();
547     ic->Activate( 0 );
548     if ( update )
549       ic->CurrentViewer()->Redraw();
550   }
551 }
552
553
554 /*!
555   \Collect objects visible in viewer
556   \param theList - visible objects collection
557 */
558 void SOCC_Viewer::GetVisible( SALOME_ListIO& theList )
559 {
560   AIS_ListOfInteractive List;
561   getAISContext()->DisplayedObjects(List);
562   
563   AIS_ListIteratorOfListOfInteractive ite(List);
564   for ( ; ite.More(); ite.Next() )
565   {
566     Handle(SALOME_InteractiveObject) anObj =
567         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
568
569     if ( !anObj.IsNull() && anObj->hasEntry() )
570       theList.Append( anObj );
571   }
572 }
573
574 /*!
575   Updates current viewer
576 */
577 void SOCC_Viewer::Repaint()
578 {
579 //  onAdjustTrihedron();
580   getViewer3d()->Update();
581 }
582
583
584 /*!
585   create SOCC_ViewWindow
586 */
587 /*SUIT_ViewWindow* SOCC_Viewer::createView( SUIT_Desktop* theDesktop )
588 {
589   SOCC_ViewWindow* view = new SOCC_ViewWindow(theDesktop, this);
590   //initView( view );
591   initView( view->getView(OCCViewer_ViewFrame::MAIN_VIEW) );
592   return view;
593   }*/
594
595 /* 
596  * Returns a new OCCViewer_ViewWindow instance which will be placed as a sub window in ViewFrame
597  */
598 OCCViewer_ViewWindow* SOCC_Viewer::createSubWindow()
599 {
600   return new SOCC_ViewWindow( 0,  this);
601 }