Salome HOME
5c2c598026b18f27a7beecd743a9c12650bc6f47
[modules/gui.git] / src / SOCC / SOCC_ViewModel.cxx
1 // Copyright (C) 2007-2022  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 = isTrihedronVisible();
416   Standard_Boolean isViewCubeDisplayed  = isViewCubeVisible();
417
418   // get objects to be erased (all currently displayed objects)
419   AIS_ListOfInteractive aList;
420   ic->DisplayedObjects( aList );
421   AIS_ListIteratorOfListOfInteractive anIter( aList );
422   for ( ; anIter.More(); anIter.Next() ) {
423     if ( isTrihedronDisplayed && anIter.Value()->DynamicType() == STANDARD_TYPE( AIS_Trihedron ) )
424       continue;
425     if ( isViewCubeDisplayed && anIter.Value()->DynamicType() == STANDARD_TYPE( AIS_ViewCube ) )
426       continue;
427
428     // erase an object
429     Handle(AIS_InteractiveObject) anIO = anIter.Value();
430     ic->Erase( anIO, false );
431     
432     // Set visibility flag if necessary
433     // Temporarily commented to avoid awful dependecy on SALOMEDS
434     // TODO: better mechanism of storing display/erse status in a study
435     // should be provided...
436     //if ( !forced ) {
437     //  Handle(SALOME_InteractiveObject) anObj =
438     //  Handle(SALOME_InteractiveObject)::DownCast( anIO->GetOwner() );
439
440     //  if ( !anObj.IsNull() && anObj->hasEntry() ) {
441     //    ToolsGUI::SetVisibility( anObj->getEntry(), true, this );
442     //  }
443     //}
444   }
445
446   SALOME_View::EraseAll( d, forced );
447
448   Repaint();
449   updateTrihedron();
450 }
451
452 /*!
453   Create presentation corresponding to the entry
454   \param entry - entry
455 */
456 SALOME_Prs* SOCC_Viewer::CreatePrs( const char* entry )
457 {
458   SOCC_Prs* prs = new SOCC_Prs(entry);
459   if ( entry )
460   {
461     if(entry2aisobjects.count(entry)>0)
462       {
463         //ais object exists
464         std::vector<Handle(AIS_InteractiveObject)> List = entry2aisobjects[entry];
465         // get context
466         Handle(AIS_InteractiveContext) ic = getAISContext();
467         //add all ais
468         for ( unsigned int ind = 0; ind < List.size(); ind++ )
469           {
470             Handle(AIS_InteractiveObject) anAIS=List[ind];
471             if(ic->IsDisplayed(anAIS))
472               {
473                 prs->AddObject( anAIS );
474               }
475           }
476       }
477   }
478   return prs;
479 }
480
481 /*!
482   Activates selection of sub-shapes
483 */
484 void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const std::list<int> modes )
485 {
486   Handle(AIS_InteractiveContext) ic = getAISContext();
487   
488   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( thePrs );
489   if ( ic.IsNull() )
490     return;
491   
492   // Open local context if there is no one
493   bool allObjects = thePrs == 0 || thePrs->IsNull();
494   ic->Deactivate();
495
496   AIS_ListOfInteractive anObjs;
497   // Get objects to be activated
498   if ( allObjects ) 
499     ic->DisplayedObjects( anObjs );
500   else
501     anOCCPrs->GetObjects( anObjs );
502
503   std::list<int> sel_modes;
504   for ( int i = TopAbs_COMPOUND; i < TopAbs_SHAPE; i++ )
505     if ( std::find(modes.begin(), modes.end(), (int)TopAbs_SHAPE) != modes.end() || std::find(modes.begin(), modes.end(), i) != modes.end())
506       sel_modes.push_back(i);
507
508   // Activate selection of objects from prs
509   AIS_ListIteratorOfListOfInteractive aIter( anObjs );
510   for ( ; aIter.More(); aIter.Next() ) {
511     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
512     if ( !anAIS.IsNull() )
513     {
514       std::list<int>::const_iterator it;
515       if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
516       {
517         ic->Load( anAIS, -1 );
518         for( it = sel_modes.begin(); it != sel_modes.end(); ++it )
519           ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)*it ) );
520       }
521       else if ( anAIS->DynamicType() == STANDARD_TYPE(AIS_ViewCube) )
522       {
523         ic->Activate( anAIS, 0 );
524       }
525       else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
526       {
527         ic->Load( anAIS, -1 );
528         for( it = sel_modes.begin(); it != sel_modes.end(); ++it )
529           ic->Activate( anAIS, *it );
530       }
531     }
532   }
533 }
534
535 /*!
536   Activates selection of sub-shapes
537 */
538 void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const int theMode )
539 {
540   std::list<int> modes;
541   modes.push_back( theMode );
542   LocalSelection( thePrs, modes );
543 }
544
545 /*!
546   Deactivates selection of sub-shapes
547 */
548 void SOCC_Viewer::GlobalSelection( const bool update ) const
549 {
550   Handle(AIS_InteractiveContext) ic = getAISContext();
551   if ( !ic.IsNull() )
552   {
553     ic->Deactivate();
554     ic->Activate( 0 );
555     if ( update )
556       ic->CurrentViewer()->Redraw();
557   }
558 }
559
560
561 /*!
562   \Collect objects visible in viewer
563   \param theList - visible objects collection
564 */
565 void SOCC_Viewer::GetVisible( SALOME_ListIO& theList )
566 {
567   AIS_ListOfInteractive List;
568   getAISContext()->DisplayedObjects(List);
569   
570   AIS_ListIteratorOfListOfInteractive ite(List);
571   for ( ; ite.More(); ite.Next() )
572   {
573     Handle(SALOME_InteractiveObject) anObj =
574         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
575
576     if ( !anObj.IsNull() && anObj->hasEntry() )
577       theList.Append( anObj );
578   }
579 }
580
581 /*!
582   Updates current viewer
583 */
584 void SOCC_Viewer::Repaint()
585 {
586 //  onAdjustTrihedron();
587   getViewer3d()->Update();
588 }
589
590
591 /*!
592   create SOCC_ViewWindow
593 */
594 /*SUIT_ViewWindow* SOCC_Viewer::createView( SUIT_Desktop* theDesktop )
595 {
596   SOCC_ViewWindow* view = new SOCC_ViewWindow(theDesktop, this);
597   //initView( view );
598   initView( view->getView(OCCViewer_ViewFrame::MAIN_VIEW) );
599   return view;
600   }*/
601
602 /* 
603  * Returns a new OCCViewer_ViewWindow instance which will be placed as a sub window in ViewFrame
604  */
605 OCCViewer_ViewWindow* SOCC_Viewer::createSubWindow()
606 {
607   return new SOCC_ViewWindow( 0,  this);
608 }