]> SALOME platform Git repositories - modules/gui.git/blob - src/SOCC/SOCC_ViewModel.cxx
Salome HOME
A revision of documentation changes in the new version. Very minor corrections.
[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( SALOME_Displayer* d, 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   SALOME_View::EraseAll( d, forced );
517
518   Repaint();
519   updateTrihedron();
520 }
521
522 /*!
523   Create presentation corresponding to the entry
524   \param entry - entry
525 */
526 SALOME_Prs* SOCC_Viewer::CreatePrs( const char* entry )
527 {
528   SOCC_Prs* prs = new SOCC_Prs(entry);
529   if ( entry )
530   {
531     if(entry2aisobjects.count(entry)>0)
532       {
533         //ais object exists
534         std::vector<Handle(AIS_InteractiveObject)> List = entry2aisobjects[entry];
535         // get context
536         Handle(AIS_InteractiveContext) ic = getAISContext();
537         //add all ais
538         for ( unsigned int ind = 0; ind < List.size(); ind++ )
539           {
540             Handle(AIS_InteractiveObject) anAIS=List[ind];
541             if(ic->IsDisplayed(anAIS))
542               {
543                 prs->AddObject( anAIS );
544               }
545           }
546       }
547   }
548   return prs;
549 }
550
551 /*!
552   Activates selection of sub-shapes
553 */
554 void SOCC_Viewer::LocalSelection( const SALOME_OCCPrs* thePrs, const int theMode )
555 {
556   Handle(AIS_InteractiveContext) ic = getAISContext();
557   
558   const SOCC_Prs* anOCCPrs = dynamic_cast<const SOCC_Prs*>( thePrs );
559   if ( ic.IsNull() )
560     return;
561   
562   // Open local context if there is no one
563   bool allObjects = thePrs == 0 || thePrs->IsNull();
564   if ( !ic->HasOpenedContext() ) {
565     ic->ClearCurrents( false );
566     ic->OpenLocalContext( allObjects, true, true );
567   }
568
569   AIS_ListOfInteractive anObjs;
570   // Get objects to be activated
571   if ( allObjects ) 
572     ic->DisplayedObjects( anObjs );
573   else
574     anOCCPrs->GetObjects( anObjs );
575
576   // Activate selection of objects from prs
577   AIS_ListIteratorOfListOfInteractive aIter( anObjs );
578   for ( ; aIter.More(); aIter.Next() ) {
579     Handle(AIS_InteractiveObject) anAIS = aIter.Value();
580     if ( !anAIS.IsNull() )
581     {
582       if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
583       {
584         ic->Load( anAIS, -1, false );
585         ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)theMode ) );
586       }
587       else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
588       {
589         ic->Load( anAIS, -1, false );
590         ic->Activate( anAIS, theMode );
591       }
592     }
593   }
594 }
595
596 /*!
597   Deactivates selection of sub-shapes
598 */
599 void SOCC_Viewer::GlobalSelection( const bool update ) const
600 {
601   Handle(AIS_InteractiveContext) ic = getAISContext();
602   if ( !ic.IsNull() )
603   {
604     ic->CloseAllContexts( false );
605     if ( update )
606       ic->CurrentViewer()->Redraw();
607   }
608 }
609
610
611 /*!
612   \Collect objects visible in viewer
613   \param theList - visible objects collection
614 */
615 void SOCC_Viewer::GetVisible( SALOME_ListIO& theList )
616 {
617   AIS_ListOfInteractive List;
618   getAISContext()->DisplayedObjects(List);
619   
620   AIS_ListIteratorOfListOfInteractive ite(List);
621   for ( ; ite.More(); ite.Next() )
622   {
623     Handle(SALOME_InteractiveObject) anObj =
624         Handle(SALOME_InteractiveObject)::DownCast( ite.Value()->GetOwner() );
625
626     if ( !anObj.IsNull() && anObj->hasEntry() )
627       theList.Append( anObj );
628   }
629 }
630
631 /*!
632   Updates current viewer
633 */
634 void SOCC_Viewer::Repaint()
635 {
636 //  onAdjustTrihedron();
637   getViewer3d()->Update();
638 }
639
640
641 /*!
642   create SOCC_ViewWindow
643 */
644 /*SUIT_ViewWindow* SOCC_Viewer::createView( SUIT_Desktop* theDesktop )
645 {
646   SOCC_ViewWindow* view = new SOCC_ViewWindow(theDesktop, this);
647   //initView( view );
648   initView( view->getView(OCCViewer_ViewFrame::MAIN_VIEW) );
649   return view;
650   }*/
651
652 /* 
653  * Returns a new OCCViewer_ViewWindow instance which will be placed as a sub window in ViewFrame
654  */
655 OCCViewer_ViewWindow* SOCC_Viewer::createSubWindow()
656 {
657   return new SOCC_ViewWindow( 0,  this);
658 }