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