Salome HOME
Bug fixes.
[modules/gui.git] / src / SOCC / SOCC_ViewModel.cxx
1 #include "SOCC_ViewModel.h"
2
3 #include "SOCC_Prs.h"
4
5 #include "SUIT_Session.h"
6 #include "SUIT_Application.h"
7
8 #include "ToolsGUI.h"
9
10 #include <SALOMEconfig.h>
11 #include CORBA_CLIENT_HEADER(SALOMEDS)
12
13 #include <AIS_ListIteratorOfListOfInteractive.hxx>
14 #include <Visual3d_View.hxx>
15
16 #include <SALOME_AISShape.hxx>
17 #include <SALOME_AISObject.hxx>
18
19 #include <Utils_ORB_INIT.hxx>
20 #include <Utils_SINGLETON.hxx>
21 #include <SALOME_ModuleCatalog_impl.hxx>
22 #include <SALOME_NamingService.hxx>
23
24 #include "SALOMEDSClient.hxx"
25 #include "SALOMEDS_StudyManager.hxx"
26
27 #include <AIS_TypeOfIso.hxx>
28
29 // in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.
30 // SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from 
31 // SALOMEDS::StudyManager - no linkage with SalomeApp. 
32
33 static _PTR(Study) getStudyDS() 
34 {
35   SALOMEDSClient_Study* aStudy = NULL;
36   _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );
37
38   // get id of SUIT_Study, if it's a SalomeApp_Study, it will return
39   //    id of its underlying SALOMEDS::Study
40   SUIT_Application* app = SUIT_Session::session()->activeApplication();
41   if ( !app )  return _PTR(Study)(aStudy); 
42   SUIT_Study* stud = app->activeStudy();
43   if ( !stud ) return _PTR(Study)(aStudy);  
44   const int id = stud->id(); // virtual method, must return SALOMEDS_Study id
45   // get SALOMEDS_Study with this id from StudyMgr
46   return aMgr->GetStudyByID( id );
47 }
48
49 SOCC_Viewer::SOCC_Viewer( bool DisplayTrihedron )
50 : OCCViewer_Viewer( DisplayTrihedron )
51 {
52 }
53
54 SOCC_Viewer::~SOCC_Viewer()
55 {
56 }
57
58 bool SOCC_Viewer::highlight( const Handle(SALOME_InteractiveObject)& obj,
59                              bool hilight, bool upd )
60 {
61   bool isInLocal = getAISContext()->HasOpenedContext();
62   //SUIT_Study* ActiveStudy = SUIT_Application::getDesktop()->getActiveStudy();
63   //SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
64
65   AIS_ListOfInteractive List;
66   getAISContext()->DisplayedObjects(List);
67   
68   AIS_ListIteratorOfListOfInteractive ite(List);
69   for ( ; ite.More(); ite.Next() )
70   {
71     Handle(SALOME_InteractiveObject) anObj =
72       Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
73
74     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
75     {
76       if ( !isInLocal )
77           OCCViewer_Viewer::highlight( ite.Value(), hilight, false );
78       // highlight subshapes only when local selection is active
79       else
80       {
81         /*if ( ite.Value()->IsKind( STANDARD_TYPE( SALOME_AISShape ) ) )
82         {
83           Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast( ite.Value() );
84           TColStd_IndexedMapOfInteger MapIndex;
85           Sel->GetIndex( IObject, MapIndex );
86           aSh->highlightSubShapes( MapIndex, highlight );
87         }*/
88       }
89       break;
90     }
91   }
92     
93   if( upd )
94     update();
95     
96   return false;
97 }
98
99 bool SOCC_Viewer::isInViewer( const Handle(SALOME_InteractiveObject)& obj,
100                               bool onlyInViewer )
101 {
102   AIS_ListOfInteractive List;
103   getAISContext()->DisplayedObjects(List);
104
105   if( !onlyInViewer ) {
106     AIS_ListOfInteractive List1;
107     getAISContext()->ObjectsInCollector(List1);
108     List.Append(List1);
109   }
110
111   AIS_ListIteratorOfListOfInteractive ite(List);
112   for ( ; ite.More(); ite.Next() )
113   {
114     Handle(SALOME_InteractiveObject) anObj =
115         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
116
117     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
118       return true;
119   }
120   return false;
121 }
122
123 bool SOCC_Viewer::isVisible( const Handle(SALOME_InteractiveObject)& obj )
124 {
125   AIS_ListOfInteractive List;
126   getAISContext()->DisplayedObjects( List );
127
128   AIS_ListIteratorOfListOfInteractive ite( List );
129   for ( ; ite.More(); ite.Next() )
130   {
131     Handle(SALOME_InteractiveObject) anObj =
132       Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
133
134     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
135       return getAISContext()->IsDisplayed( ite.Value() );
136   }
137   
138   return false;
139 }
140
141 void SOCC_Viewer::setColor( const Handle(SALOME_InteractiveObject)& obj,
142                             const QColor& color, bool update )
143 {
144   AIS_ListOfInteractive List;
145   getAISContext()->DisplayedObjects(List);
146   
147   AIS_ListIteratorOfListOfInteractive ite(List);
148   for ( ; ite.More(); ite.Next() )
149   {
150     Handle(SALOME_InteractiveObject) anObj =
151         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
152
153     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
154     {
155       OCCViewer_Viewer::setColor( ite.Value(), color, update );
156       return;
157     }
158   }
159 }
160
161 void SOCC_Viewer::switchRepresentation( const Handle(SALOME_InteractiveObject)& obj,
162                                         int mode, bool update )
163 {
164   AIS_ListOfInteractive List;
165   getAISContext()->DisplayedObjects(List);
166   
167   AIS_ListIteratorOfListOfInteractive ite(List);
168   for ( ; ite.More(); ite.Next() )
169   {
170     Handle(SALOME_InteractiveObject) anObj =
171         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
172
173     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
174     {
175       OCCViewer_Viewer::switchRepresentation( ite.Value(), mode, update );
176       return;
177     }
178   }
179 }
180
181 void SOCC_Viewer::setTransparency( const Handle(SALOME_InteractiveObject)& obj,
182                                    float trans, bool update )
183 {
184   AIS_ListOfInteractive List;
185   getAISContext()->DisplayedObjects( List );
186   
187   AIS_ListIteratorOfListOfInteractive ite( List );
188   for ( ; ite.More(); ite.Next() )
189   {
190     Handle(SALOME_InteractiveObject) anObj =
191         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
192
193     if ( !anObj.IsNull() && anObj->hasEntry() && anObj->isSame( obj ) )
194     {
195       OCCViewer_Viewer::setTransparency( ite.Value(), trans, update );
196       return;
197     }
198   }
199 }
200
201 void SOCC_Viewer::rename( const Handle(SALOME_InteractiveObject)& obj,
202                           const QString& name )
203 {
204   AIS_ListOfInteractive List;
205   getAISContext()->DisplayedObjects(List);
206   
207   AIS_ListIteratorOfListOfInteractive ite(List);
208   while (ite.More())
209   {
210     if (ite.Value()->IsKind(STANDARD_TYPE(SALOME_AISShape)))
211     {
212       Handle(SALOME_AISShape) aSh = Handle(SALOME_AISShape)::DownCast(ite.Value());
213       
214       if ( aSh->hasIO() )
215       {
216         Handle(SALOME_InteractiveObject) IO = aSh->getIO();
217         if ( IO->isSame( obj ) )
218         {
219           aSh->setName( (char*)name.latin1() );
220           break;
221         }
222       }
223     }
224     else if ( ite.Value()->IsKind( STANDARD_TYPE( SALOME_AISObject ) ) )
225     {
226       Handle(SALOME_AISObject) aSh = Handle(SALOME_AISObject)::DownCast( ite.Value() );
227
228       // Add code here, if someone create a MODULE_AISObject.
229     }
230     ite.Next();
231   }
232 }
233
234 //=======================================================================
235 // name    : Display
236 // Purpose : Display presentation
237 //=======================================================================
238 void SOCC_Viewer::Display( const SALOME_OCCPrs* prs )
239 {
240   // try do downcast object
241   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( prs );
242   if ( !anOCCPrs || anOCCPrs->IsNull() )
243     return;
244
245   // get SALOMEDS Study
246   _PTR(Study) study(getStudyDS());
247
248   // get context
249   Handle (AIS_InteractiveContext) ic = getAISContext();
250
251   // get all displayed objects
252   AIS_ListOfInteractive List;
253   ic->DisplayedObjects( List );
254   // get objects in the collector
255   AIS_ListOfInteractive ListCollector;
256   ic->ObjectsInCollector( ListCollector );
257
258   // get objects to be displayed
259   AIS_ListOfInteractive anAISObjects;
260   anOCCPrs->GetObjects( anAISObjects );
261
262   AIS_ListIteratorOfListOfInteractive aIter( anAISObjects );
263   for ( ; aIter.More(); aIter.Next() )
264   {
265     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
266     if ( !anAIS.IsNull() )
267     {
268       // try to find presentation in the viewer
269       bool bDisplayed = false;
270       AIS_ListIteratorOfListOfInteractive ite( List );
271       for ( ; ite.More(); ite.Next() )
272       {
273         // compare presentations by handles
274         // if the object is already displayed - nothing to do more
275         if ( ite.Value() == anAIS )
276         {
277           // Deactivate object if necessary
278           if ( !anOCCPrs->ToActivate() )
279             ic->Deactivate( anAIS );
280           bDisplayed = true;
281           break;
282         }
283       }
284
285       if ( bDisplayed )
286         continue;
287
288       // then try to find presentation in the collector
289       bDisplayed = false;
290       ite.Initialize( ListCollector );
291       for ( ; ite.More(); ite.Next() )
292       {
293         // compare presentations by handles
294         // if the object is in collector - display it
295         if ( ite.Value() == anAIS )
296         {
297           ic->DisplayFromCollector( anAIS, false );
298
299           // Deactivate object if necessary
300           if ( !anOCCPrs->ToActivate() )
301             ic->Deactivate( anAIS );
302           bDisplayed = true;
303
304           // Set visibility flag
305           Handle(SALOME_InteractiveObject) anObj =
306             Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
307           if ( !anObj.IsNull() && anObj->hasEntry() )
308           {
309             if ( study )
310               ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
311           }
312
313           break;
314         }
315       }
316       if ( bDisplayed )
317         continue;
318
319       // if object is not displayed and not found in the collector - display it
320       if ( anAIS->IsKind( STANDARD_TYPE(AIS_Trihedron) ) )
321       {
322         Handle(AIS_Trihedron) aTrh = Handle(AIS_Trihedron)::DownCast( anAIS );
323         double aNewSize = 100, aSize = 100;
324         getTrihedronSize( aNewSize, aSize );
325         aTrh->SetSize( aTrh == getTrihedron() ? aNewSize : 0.5 * aNewSize );
326       }
327
328       ic->Display( anAIS, false );
329
330       // Set visibility flag
331       Handle(SALOME_InteractiveObject) anObj =
332         Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
333       if ( !anObj.IsNull() && anObj->hasEntry() )
334       {
335         if ( study  )
336           ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
337       }
338
339       // Deactivate object if necessary
340       if ( !anOCCPrs->ToActivate() )
341         ic->Deactivate( anAIS );
342     }
343   }
344 }
345
346 //=======================================================================
347 // name    : Erase
348 // Purpose : Erase presentation
349 //=======================================================================
350 void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced )
351 {
352   // try do downcast object
353   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( prs );
354   if ( !anOCCPrs || anOCCPrs->IsNull() )
355     return;
356
357   // get SALOMEDS Study
358   _PTR(Study) study(getStudyDS());
359
360   // get context
361   Handle(AIS_InteractiveContext) ic = getAISContext();
362
363   // get objects to be erased
364   AIS_ListOfInteractive anAISObjects;
365   anOCCPrs->GetObjects( anAISObjects );
366
367   AIS_ListIteratorOfListOfInteractive aIter( anAISObjects );
368   for ( ; aIter.More(); aIter.Next() ) {
369     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
370     if ( !anAIS.IsNull() ) {
371       // erase the object from context : move it to collector
372       ic->Erase( anAIS, false, forced ? false : true );
373
374       // Set visibility flag if necessary
375       if ( !forced )
376       {
377         Handle(SALOME_InteractiveObject) anObj =
378           Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
379         if ( !anObj.IsNull() && anObj->hasEntry() )
380         {
381           if ( study )
382             ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
383         }
384       }
385     }
386   }
387 }
388
389 //=======================================================================
390 // name    : EraseAll
391 // Purpose : Erase all presentations
392 //=======================================================================
393 void SOCC_Viewer::EraseAll( const bool forced )
394 {
395   // get SALOMEDS Study
396   _PTR(Study) study(getStudyDS());
397
398   // get context
399   Handle(AIS_InteractiveContext) ic = getAISContext();
400
401   // check if trihedron is displayed
402   Standard_Boolean isTrihedronDisplayed = ic->IsDisplayed( getTrihedron() );
403
404   // get objects to be erased (all currently displayed objects)
405   AIS_ListOfInteractive aList;
406   ic->DisplayedObjects( aList );
407   AIS_ListIteratorOfListOfInteractive anIter( aList );
408   for ( ; anIter.More(); anIter.Next() ) {
409     if ( isTrihedronDisplayed && anIter.Value()->DynamicType() == STANDARD_TYPE( AIS_Trihedron ) )
410       continue;
411
412     // erase an object
413     Handle(AIS_InteractiveObject) anIO = anIter.Value();
414     ic->Erase( anIO, false, forced ? false : true );
415     
416     // Set visibility flag if necessary
417     if ( !forced ) {
418       Handle(SALOME_InteractiveObject) anObj =
419         Handle(SALOME_InteractiveObject)::DownCast( anIO->GetOwner() );
420
421       if ( !anObj.IsNull() && anObj->hasEntry() ) {
422         if ( study )
423           ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
424       }
425     }
426   }
427
428   // display trihedron if necessary
429   if ( isTrihedronDisplayed )
430     getAISContext()->Display( getTrihedron() );
431   else
432     Repaint();
433 }
434
435 //=======================================================================
436 // name    : CreatePrs
437 // Purpose : Create presentation corresponding to the entry
438 //=======================================================================
439 SALOME_Prs* SOCC_Viewer::CreatePrs( const char* entry )
440 {
441   SOCC_Prs* prs = new SOCC_Prs();
442   if ( entry )
443   {
444     // get context
445     Handle(AIS_InteractiveContext) ic = getAISContext();
446
447     // get displayed objects
448     AIS_ListOfInteractive List;
449     ic->DisplayedObjects( List );
450     // get objects in the collector
451     AIS_ListOfInteractive ListCollector;
452     ic->ObjectsInCollector( ListCollector );
453     List.Append( ListCollector );
454
455     AIS_ListIteratorOfListOfInteractive ite( List );
456     for ( ; ite.More(); ite.Next() )
457     {
458       Handle(SALOME_InteractiveObject) anObj =
459         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
460
461       if ( !anObj.IsNull() && anObj->hasEntry() && strcmp( anObj->getEntry(), entry ) == 0 )
462         prs->AddObject( ite.Value() );
463     }
464   }
465   return prs;
466 }
467
468 //=======================================================================
469 // name    : LocalSelection
470 // Purpose : Activates selection of sub shapes
471 //=======================================================================
472 void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const int theMode )
473 {
474   Handle(AIS_InteractiveContext) ic = getAISContext();
475   
476   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( thePrs );
477   if ( ic.IsNull() )
478     return;
479   
480   // Open local context if there is no one
481   bool allObjects = thePrs == 0 || thePrs->IsNull();
482   if ( !ic->HasOpenedContext() ) {
483     ic->ClearCurrents( false );
484     ic->OpenLocalContext( allObjects, true, true );
485   }
486
487   AIS_ListOfInteractive anObjs;
488   // Get objects to be activated
489   if ( allObjects ) 
490     ic->DisplayedObjects( anObjs );
491   else
492     anOCCPrs->GetObjects( anObjs );
493
494   // Activate selection of objects from prs
495   AIS_ListIteratorOfListOfInteractive aIter( anObjs );
496   for ( ; aIter.More(); aIter.Next() ) {
497     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
498     if ( !anAIS.IsNull() )
499     {
500       if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
501       {
502         ic->Load( anAIS, -1, false );
503         ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)theMode ) );
504       }
505       else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
506       {
507         ic->Load( anAIS, -1, false );
508         ic->Activate( anAIS, theMode );
509       }
510     }
511   }
512 }
513
514 //=======================================================================
515 // name    : GlobalSelection
516 // Purpose : Deactivates selection of sub shapes
517 //=======================================================================
518 void SOCC_Viewer::GlobalSelection( const bool update ) const
519 {
520   Handle(AIS_InteractiveContext) ic = getAISContext();
521   if ( !ic.IsNull() )
522   {
523     ic->CloseAllContexts( false );
524     if ( update )
525       ic->CurrentViewer()->Redraw();
526   }
527 }
528
529 //=======================================================================
530 // name    : BeforeDisplay
531 // Purpose : Axiluary method called before displaying of objects
532 //=======================================================================
533 void  SOCC_Viewer::BeforeDisplay( SALOME_Displayer* d )
534 {
535   d->BeforeDisplay( this, SALOME_OCCViewType() );
536 }
537
538 //=======================================================================
539 // name    : AfterDisplay
540 // Purpose : Axiluary method called after displaying of objects
541 //=======================================================================
542 void SOCC_Viewer::AfterDisplay( SALOME_Displayer* d )
543 {
544   d->AfterDisplay( this, SALOME_OCCViewType() );
545 }
546
547 //=======================================================================
548 // name    : getTrihedronSize
549 // Purpose : Get new and current trihedron size corresponding to the
550 //           current model size
551 //=======================================================================
552 bool SOCC_Viewer::getTrihedronSize( double& theNewSize, double& theSize )
553 {
554   theNewSize = 100;
555   theSize = 100;
556
557   //SRN: BUG IPAL8996, a usage of method ActiveView without an initialization
558   Handle(V3d_Viewer) viewer = getViewer3d();
559   viewer->InitActiveViews();
560   if(!viewer->MoreActiveViews()) return false;
561
562   Handle(V3d_View) view3d = viewer->ActiveView();
563   //SRN: END of fix
564
565   if ( view3d.IsNull() )
566     return false;
567
568   double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
569   double aMaxSide;
570
571   view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
572
573   if ( Xmin == RealFirst() || Ymin == RealFirst() || Zmin == RealFirst() ||
574        Xmax == RealLast()  || Ymax == RealLast()  || Zmax == RealLast() )
575     return false;
576
577   aMaxSide = Xmax - Xmin;
578   if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin;
579   if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin;
580
581   float aSizeInPercents = SUIT_Session::session()->resourceMgr()->doubleValue("Viewer:TrihedronSize", 105.);
582
583   static float EPS = 5.0E-3;
584   theSize = getTrihedron()->Size();
585   theNewSize = aMaxSide*aSizeInPercents / 100.0;
586
587   return fabs( theNewSize - theSize ) > theSize * EPS ||
588          fabs( theNewSize - theSize) > theNewSize * EPS;
589 }
590
591 //=======================================================================
592 // name    : Repaint
593 // Purpose : 
594 //=======================================================================
595 void SOCC_Viewer::Repaint()
596 {
597 //  onAdjustTrihedron();
598   getViewer3d()->Update();
599 }