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