Salome HOME
Remove obsolete OCC_VERSION_LARGE defines.
[modules/gui.git] / src / SOCC / SOCC_ViewModel.cxx
1 // Copyright (C) 2007-2014  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 "OCCViewer_Trihedron.h"
29
30 #include "SUIT_Session.h"
31 #include "SUIT_ResourceMgr.h"
32 //#include "SUIT_Application.h"
33
34 //#include "ToolsGUI.h"
35
36 // Temporarily commented to avoid awful dependecy on SALOMEDS
37 // TODO: better mechanism of storing display/erse status in a study
38 // should be provided...
39 //#include <SALOMEconfig.h>
40 //#include CORBA_CLIENT_HEADER(SALOMEDS)
41
42 #include <AIS_ListIteratorOfListOfInteractive.hxx>
43 #include <Visual3d_View.hxx>
44
45 #include <SALOME_AISShape.hxx>
46 #include <SALOME_AISObject.hxx>
47 #include <SALOME_InteractiveObject.hxx>
48 #include <SALOME_ListIO.hxx>
49
50 // Temporarily commented to avoid awful dependecy on SALOMEDS
51 // TODO: better mechanism of storing display/erse status in a study
52 // should be provided...
53 //#include <Utils_ORB_INIT.hxx>
54 //#include <Utils_SINGLETON.hxx>
55 //#include <SALOME_ModuleCatalog_impl.hxx>
56 //#include <SALOME_NamingService.hxx>
57
58 //#include "SALOMEDSClient.hxx"
59 //#include "SALOMEDS_StudyManager.hxx"
60 #include <Basics_OCCTVersion.hxx>
61
62 #include <AIS_TypeOfIso.hxx>
63 #include <Precision.hxx>
64
65 // in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.
66 // SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from 
67 // SALOMEDS::StudyManager - no linkage with SalomeApp. 
68
69 // Temporarily commented to avoid awful dependecy on SALOMEDS
70 // TODO: better mechanism of storing display/erse status in a study
71 // should be provided...
72 //static _PTR(Study) getStudyDS() 
73 //{
74 //  SALOMEDSClient_Study* aStudy = NULL;
75 //  _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );
76
77   // get id of SUIT_Study, if it's a SalomeApp_Study, it will return
78   //    id of its underlying SALOMEDS::Study
79 //  SUIT_Application* app = SUIT_Session::session()->activeApplication();
80 //  if ( !app )  return _PTR(Study)(aStudy);
81 //  SUIT_Study* stud = app->activeStudy();
82 //  if ( !stud ) return _PTR(Study)(aStudy);  
83 //  const int id = stud->id(); // virtual method, must return SALOMEDS_Study id
84   // get SALOMEDS_Study with this id from StudyMgr
85 //  return aMgr->GetStudyByID( id );
86 //}
87
88 /*!
89   Constructor
90   \param DisplayTrihedron - is trihedron displayed
91 */
92 SOCC_Viewer::SOCC_Viewer( bool DisplayTrihedron )
93 : OCCViewer_Viewer( DisplayTrihedron )
94 {
95 }
96
97 /*!
98   Destructor
99 */
100 SOCC_Viewer::~SOCC_Viewer()
101 {
102 }
103
104 /*!
105   Hilights/unhilights object in viewer
106   \param obj - object to be updated
107   \param hilight - if it is true, object will be hilighted, otherwise it will be unhilighted
108   \param update - update current viewer
109 */
110 bool SOCC_Viewer::highlight( const Handle(SALOME_InteractiveObject)& obj,
111                              bool hilight, bool upd )
112 {
113   bool isInLocal = getAISContext()->HasOpenedContext();
114   //SUIT_Study* ActiveStudy = SUIT_Application::getDesktop()->getActiveStudy();
115   //SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
116
117   AIS_ListOfInteractive List;
118   getAISContext()->DisplayedObjects(List);
119   
120   AIS_ListIteratorOfListOfInteractive ite(List);
121   for ( ; ite.More(); ite.Next() )
122   {
123     Handle(SALOME_InteractiveObject) anObj =
124       Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
125
126     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
127     {
128       if ( !isInLocal )
129           OCCViewer_Viewer::highlight( ite.Value(), hilight, false );
130       // highlight sub-shapes only when local selection is active
131       else
132       {
133         /*if ( ite.Value()->IsKind( STANDARD_TYPE( SALOME_AISShape ) ) )
134         {
135           Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast( ite.Value() );
136           TColStd_IndexedMapOfInteger MapIndex;
137           Sel->GetIndex( IObject, MapIndex );
138           aSh->highlightSubShapes( MapIndex, highlight );
139         }*/
140       }
141       break;
142     }
143   }
144     
145   if( upd )
146     update();
147     
148   return false;
149 }
150
151 /*!
152   \return true if object is in viewer or in collector
153   \param obj - object to be checked
154   \param onlyInViewer - search object only in viewer (so object must be displayed)
155 */
156 bool SOCC_Viewer::isInViewer( const Handle(SALOME_InteractiveObject)& obj,
157                               bool onlyInViewer )
158 {
159   AIS_ListOfInteractive List;
160   getAISContext()->DisplayedObjects(List);
161   AIS_ListIteratorOfListOfInteractive ite(List);
162   for ( ; ite.More(); ite.Next() )
163   {
164     Handle(SALOME_InteractiveObject) anObj =
165         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
166
167     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
168       return true;
169   }
170   return false;
171 }
172
173 /*!
174   \return true if object is displayed in viewer
175   \param obj - object to be checked
176 */
177 bool SOCC_Viewer::isVisible( const Handle(SALOME_InteractiveObject)& obj )
178 {
179
180   std::map< std::string , std::vector<Handle(AIS_InteractiveObject)> >::iterator it=entry2aisobjects.find(obj->getEntry());
181   if(it != entry2aisobjects.end())
182     {
183       // get context
184       Handle (AIS_InteractiveContext) ic = getAISContext();
185       std::vector<Handle(AIS_InteractiveObject)>& List = it->second;
186       for( unsigned int ind = 0; ind < List.size(); ind++ )
187         {
188           Handle(AIS_InteractiveObject) anAIS=List[ind];
189           if(ic->IsDisplayed(anAIS))
190             return true;
191         }
192   }
193   
194   return false;
195 }
196
197 /*!
198   Sets color of object
199   \param obj - object to be updated
200   \param color - new color
201   \param update - update current viewer
202 */
203 void SOCC_Viewer::setColor( const Handle(SALOME_InteractiveObject)& obj,
204                             const QColor& color, bool update )
205 {
206   if(obj.IsNull() || !obj->hasEntry() )
207     return;
208
209   if(entry2aisobjects.count(obj->getEntry())>0)
210     {
211       // get context
212       Handle (AIS_InteractiveContext) ic = getAISContext();
213       std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[obj->getEntry()];
214       for( unsigned int ind = 0; ind < List.size(); ind++ )
215         {
216           Handle(AIS_InteractiveObject) anAIS=List[ind];
217           if( !anAIS.IsNull() && ic->IsDisplayed(anAIS))
218             OCCViewer_Viewer::setColor( anAIS, color, update );
219         }
220     }
221 }
222
223 /*!
224   Changes display mode of object
225   \param obj - object to be processed
226   \param mode - new display mode
227   \param update - update current viewer
228 */
229 void SOCC_Viewer::switchRepresentation( const Handle(SALOME_InteractiveObject)& obj,
230                                         int mode, bool update )
231 {
232   if(obj.IsNull() || !obj->hasEntry() )
233     return;
234
235   if(entry2aisobjects.count(obj->getEntry())>0)
236     {
237       // get context
238       Handle (AIS_InteractiveContext) ic = getAISContext();
239       std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[obj->getEntry()];
240       for( unsigned int ind = 0; ind < List.size(); ind++ )
241         {
242           Handle(AIS_InteractiveObject) anAIS=List[ind];
243           if( !anAIS.IsNull() && ic->IsDisplayed(anAIS))
244             OCCViewer_Viewer::switchRepresentation( anAIS, mode, update );
245         }
246     }
247 }
248
249 /*!
250   Changes transparency of object
251   \param obj - object to be processed
252   \param trans - new transparency
253   \param update - update current viewer
254 */
255 void SOCC_Viewer::setTransparency( const Handle(SALOME_InteractiveObject)& obj,
256                                    float trans, bool update )
257 {
258   if(obj.IsNull() || !obj->hasEntry() )
259     return;
260
261   if(entry2aisobjects.count(obj->getEntry())>0)
262     {
263       // get context
264       Handle (AIS_InteractiveContext) ic = getAISContext();
265       std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[obj->getEntry()];
266       for( unsigned int ind = 0; ind < List.size(); ind++ )
267         {
268           Handle(AIS_InteractiveObject) anAIS=List[ind];
269           if( !anAIS.IsNull() && ic->IsDisplayed(anAIS))
270             OCCViewer_Viewer::setTransparency( anAIS, trans, update );
271         }
272     }
273 }
274
275 /*!
276   Changes name of object
277   \param obj - object to be renamed
278   \param name - new name
279 */
280 void SOCC_Viewer::rename( const Handle(SALOME_InteractiveObject)& obj,
281                           const QString& name )
282 {
283   AIS_ListOfInteractive List;
284   getAISContext()->DisplayedObjects(List);
285   
286   AIS_ListIteratorOfListOfInteractive ite(List);
287   while (ite.More())
288   {
289     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape)))
290     {
291       Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast(ite.Value());
292       
293       if ( aSh->hasIO() )
294       {
295         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
296         if ( IO->isSame( obj ) )
297         {
298           aSh->setName( name.toLatin1().data() );
299           break;
300         }
301       }
302     }
303     else if ( ite.Value()->IsKind( STANDARD_TYPE( SALOME_AISObject ) ) )
304     {
305       Handle(SALOME_AISObject) aSh = Handle(SALOME_AISObject)::DownCast( ite.Value() );
306
307       // Add code here, if someone create a MODULE_AISObject.
308     }
309     ite.Next();
310   }
311 }
312
313
314 /*!
315   Display presentation
316   \param prs - presentation
317 */
318 void SOCC_Viewer::Display( const SALOME_OCCPrs* prs )
319 {
320   // try do downcast object
321   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( prs );
322   if ( !anOCCPrs || anOCCPrs->IsNull() )
323     return;
324
325   // get SALOMEDS Study
326   // Temporarily commented to avoid awful dependecy on SALOMEDS
327   // TODO: better mechanism of storing display/erse status in a study
328   // should be provided...
329   //  _PTR(Study) study(getStudyDS());
330
331   // get context
332   Handle (AIS_InteractiveContext) ic = getAISContext();
333
334   // get objects to be displayed
335   AIS_ListOfInteractive anAISObjects;
336   anOCCPrs->GetObjects( anAISObjects );
337
338   AIS_ListIteratorOfListOfInteractive aIter( anAISObjects );
339   for ( ; aIter.More(); aIter.Next() )
340   {
341     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
342     if ( !anAIS.IsNull() )
343     {
344       // try to find presentation in the viewer
345
346       // if the object is already displayed - nothing to do more
347       if(ic->IsDisplayed(anAIS))
348         {
349           // Deactivate object if necessary
350           if ( !anOCCPrs->ToActivate() )
351             ic->Deactivate( anAIS );
352           continue;
353         }
354
355       // if object is not displayed and not found in the collector - display it
356       if ( anAIS->IsKind( STANDARD_TYPE(AIS_Trihedron) ) )
357       {
358         Handle(AIS_Trihedron) aTrh = Handle(AIS_Trihedron)::DownCast( anAIS );
359         double aNewSize = 100, aSize = 100;
360         computeTrihedronSize( aNewSize, aSize );
361         aTrh->SetSize( aTrh == getTrihedron() ? aNewSize : 0.5 * aNewSize );
362       }
363
364       ic->Display( anAIS, false );
365       Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast (anAIS);
366       if (!aSh.IsNull())
367       {
368         aSh->SetClippable (prs->IsClippable());
369         applyExistingClipPlanesToObject (anAIS);
370         bool top = (aSh->isTopLevel() && aSh->switchTopLevel());
371               ic->SetZLayer( aSh, top ? getTopLayerId() : 0 );
372                     if(!aSh->toActivate())
373         {
374                             ic->Deactivate( aSh );
375                     }
376       }
377
378       //Register anAIS (if it has an entry) in entry2aisobjects map
379       Handle(SALOME_InteractiveObject) anObj = Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
380       if ( !anObj.IsNull() && anObj->hasEntry())
381         {
382           std::vector<Handle(AIS_InteractiveObject)>& List = entry2aisobjects[anObj->getEntry()];
383           int found=0;
384           for ( unsigned int ind = 0; ind < List.size(); ind++ )
385           {
386             if(List[ind] == anAIS)
387               {
388                 found=1;
389                 break;
390               }
391           }
392           if(!found)
393             {
394               List.push_back(anAIS);
395             }
396         }
397
398       // Set visibility flag
399       // Temporarily commented to avoid awful dependecy on SALOMEDS
400       // TODO: better mechanism of storing display/erse status in a study
401       // should be provided...
402       //Handle(SALOME_InteractiveObject) anObj =
403       //  Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
404       //if ( !anObj.IsNull() && anObj->hasEntry() )
405       //{
406       //  if ( study  )
407       //    ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
408       //}
409
410       // Deactivate object if necessary
411       if ( !anOCCPrs->ToActivate() )
412         ic->Deactivate( anAIS );
413     }
414   }
415   updateTrihedron();
416 }
417
418
419 /*!
420   Erase presentation
421   \param prs - presentation
422   \param forced - removes object from context
423 */
424 void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced )
425 {
426   // try do downcast object
427   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( prs );
428   if ( !anOCCPrs || anOCCPrs->IsNull() )
429     return;
430
431   // get SALOMEDS Study
432   // Temporarily commented to avoid awful dependecy on SALOMEDS
433   // TODO: better mechanism of storing display/erse status in a study
434   // should be provided...
435   //  _PTR(Study) study(getStudyDS());
436
437   // get context
438   Handle(AIS_InteractiveContext) ic = getAISContext();
439
440   // get objects to be erased
441   AIS_ListOfInteractive anAISObjects;
442   anOCCPrs->GetObjects( anAISObjects );
443
444   AIS_ListIteratorOfListOfInteractive aIter( anAISObjects );
445   for ( ; aIter.More(); aIter.Next() ) {
446     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
447     if ( !anAIS.IsNull() ) {
448       // erase the object from context : move it to collector
449       ic->Erase( anAIS, false );
450       // Set visibility flag if necessary
451       // Temporarily commented to avoid awful dependecy on SALOMEDS
452       // TODO: better mechanism of storing display/erse status in a study
453       // should be provided...
454       //if ( !forced )
455       //{
456       //  Handle(SALOME_InteractiveObject) anObj =
457       //    Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
458       //  if ( !anObj.IsNull() && anObj->hasEntry() )
459       //  {
460       //  if ( study )
461       //    ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
462       //  }
463       //}
464     }
465   }
466   updateTrihedron();
467 }
468
469
470 /*!
471   Erase all presentations
472   \param forced - removes all objects from context
473 */
474 void SOCC_Viewer::EraseAll( const bool forced )
475 {
476   // get SALOMEDS Study
477   // Temporarily commented to avoid awful dependecy on SALOMEDS
478   // TODO: better mechanism of storing display/erse status in a study
479   // should be provided...
480   //  _PTR(Study) study(getStudyDS());
481
482   // get context
483   Handle(AIS_InteractiveContext) ic = getAISContext();
484
485   // check if trihedron is displayed
486   Standard_Boolean isTrihedronDisplayed = ic->IsDisplayed( getTrihedron() );
487
488   // get objects to be erased (all currently displayed objects)
489   AIS_ListOfInteractive aList;
490   ic->DisplayedObjects( aList );
491   AIS_ListIteratorOfListOfInteractive anIter( aList );
492   for ( ; anIter.More(); anIter.Next() ) {
493     if ( (isTrihedronDisplayed && anIter.Value()->DynamicType() == STANDARD_TYPE( AIS_Trihedron )) ||
494          anIter.Value()->DynamicType() == STANDARD_TYPE( OCCViewer_Trihedron ))
495       continue;
496
497     // erase an object
498     Handle(AIS_InteractiveObject) anIO = anIter.Value();
499     ic->Erase( anIO, false );
500     
501     // Set visibility flag if necessary
502     // Temporarily commented to avoid awful dependecy on SALOMEDS
503     // TODO: better mechanism of storing display/erse status in a study
504     // should be provided...
505     //if ( !forced ) {
506     //  Handle(SALOME_InteractiveObject) anObj =
507     //  Handle(SALOME_InteractiveObject)::DownCast( anIO->GetOwner() );
508
509     //  if ( !anObj.IsNull() && anObj->hasEntry() ) {
510     //  if ( study )
511     //    ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
512     //  }
513     //}
514   }
515
516   Repaint();
517   updateTrihedron();
518 }
519
520 /*!
521   Create presentation corresponding to the entry
522   \param entry - entry
523 */
524 SALOME_Prs* SOCC_Viewer::CreatePrs( const char* entry )
525 {
526   SOCC_Prs* prs = new SOCC_Prs();
527   if ( entry )
528   {
529     if(entry2aisobjects.count(entry)>0)
530       {
531         //ais object exists
532         std::vector<Handle(AIS_InteractiveObject)> List = entry2aisobjects[entry];
533         // get context
534         Handle(AIS_InteractiveContext) ic = getAISContext();
535         //add all ais
536         for ( unsigned int ind = 0; ind < List.size(); ind++ )
537           {
538             Handle(AIS_InteractiveObject) anAIS=List[ind];
539             if(ic->IsDisplayed(anAIS))
540               {
541                 prs->AddObject( anAIS );
542               }
543           }
544       }
545   }
546   return prs;
547 }
548
549 /*!
550   Activates selection of sub-shapes
551 */
552 void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const int theMode )
553 {
554   Handle(AIS_InteractiveContext) ic = getAISContext();
555   
556   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( thePrs );
557   if ( ic.IsNull() )
558     return;
559   
560   // Open local context if there is no one
561   bool allObjects = thePrs == 0 || thePrs->IsNull();
562   if ( !ic->HasOpenedContext() ) {
563     ic->ClearCurrents( false );
564     ic->OpenLocalContext( allObjects, true, true );
565   }
566
567   AIS_ListOfInteractive anObjs;
568   // Get objects to be activated
569   if ( allObjects ) 
570     ic->DisplayedObjects( anObjs );
571   else
572     anOCCPrs->GetObjects( anObjs );
573
574   // Activate selection of objects from prs
575   AIS_ListIteratorOfListOfInteractive aIter( anObjs );
576   for ( ; aIter.More(); aIter.Next() ) {
577     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
578     if ( !anAIS.IsNull() )
579     {
580       if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
581       {
582         ic->Load( anAIS, -1, false );
583         ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)theMode ) );
584       }
585       else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
586       {
587         ic->Load( anAIS, -1, false );
588         ic->Activate( anAIS, theMode );
589       }
590     }
591   }
592 }
593
594 /*!
595   Deactivates selection of sub-shapes
596 */
597 void SOCC_Viewer::GlobalSelection( const bool update ) const
598 {
599   Handle(AIS_InteractiveContext) ic = getAISContext();
600   if ( !ic.IsNull() )
601   {
602     ic->CloseAllContexts( false );
603     if ( update )
604       ic->CurrentViewer()->Redraw();
605   }
606 }
607
608
609 /*!
610   \Collect objects visible in viewer
611   \param theList - visible objects collection
612 */
613 void SOCC_Viewer::GetVisible( SALOME_ListIO& theList )
614 {
615   AIS_ListOfInteractive List;
616   getAISContext()->DisplayedObjects(List);
617   
618   AIS_ListIteratorOfListOfInteractive ite(List);
619   for ( ; ite.More(); ite.Next() )
620   {
621     Handle(SALOME_InteractiveObject) anObj =
622         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
623
624     if ( !anObj.IsNull() && anObj->hasEntry() )
625       theList.Append( anObj );
626   }
627 }
628
629 /*!
630   Updates current viewer
631 */
632 void SOCC_Viewer::Repaint()
633 {
634 //  onAdjustTrihedron();
635   getViewer3d()->Update();
636 }
637
638
639 /*!
640   create SOCC_ViewWindow
641 */
642 /*SUIT_ViewWindow* SOCC_Viewer::createView( SUIT_Desktop* theDesktop )
643 {
644   SOCC_ViewWindow* view = new SOCC_ViewWindow(theDesktop, this);
645   //initView( view );
646   initView( view->getView(OCCViewer_ViewFrame::MAIN_VIEW) );
647   return view;
648   }*/
649
650 /* 
651  * Returns a new OCCViewer_ViewWindow instance which will be placed as a sub window in ViewFrame
652  */
653 OCCViewer_ViewWindow* SOCC_Viewer::createSubWindow()
654 {
655   return new SOCC_ViewWindow( 0,  this);
656 }