Salome HOME
merge master
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Selection.cxx
1 // Copyright (C) 2007-2015  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 // SMESH SMESHGUI_Selection
24 // File   : SMESHGUI_Selection.cxx
25 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
26 //
27
28 // SMESH includes
29 #include "SMESHGUI_Selection.h"
30
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_GEOMGenUtils.h"
34 #include "SMESHGUI_ComputeDlg.h"
35
36 #include <SMESH_Type.h>
37 #include <SMESH_Actor.h>
38 #include <SMESH_ScalarBarActor.h>
39
40 // SALOME GUI includes
41 #include <SalomeApp_Study.h>
42 #include <LightApp_VTKSelector.h>
43 #include <SVTK_ViewWindow.h>
44
45 // IDL includes
46 #include <SALOMEconfig.h>
47 #include CORBA_CLIENT_HEADER(SMESH_Gen)
48 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
49 #include CORBA_CLIENT_HEADER(SMESH_Group)
50
51 //=======================================================================
52 //function : SMESHGUI_Selection
53 //purpose  : 
54 //=======================================================================
55 SMESHGUI_Selection::SMESHGUI_Selection()
56 : LightApp_Selection()
57 {
58 }
59
60 //=======================================================================
61 //function : ~SMESHGUI_Selection
62 //purpose  : 
63 //=======================================================================
64 SMESHGUI_Selection::~SMESHGUI_Selection()
65 {
66 }
67
68 //=======================================================================
69 //function : init
70 //purpose  : 
71 //=======================================================================
72 void SMESHGUI_Selection::init( const QString& client, LightApp_SelectionMgr* mgr )
73 {
74   LightApp_Selection::init( client, mgr );
75
76   if( mgr && study() )
77   {
78     SalomeApp_Study* aSStudy = dynamic_cast<SalomeApp_Study*>(study());
79     if (!aSStudy)
80       return;
81     _PTR(Study) aStudy = aSStudy->studyDS();
82
83     for( int i=0, n=count(); i<n; i++ ) {
84       myTypes.append( typeName( type( entry( i ), aStudy ) ) );
85       myControls.append( controlMode( i ) );
86     }
87   }
88 }
89
90 //=======================================================================
91 //function : processOwner
92 //purpose  : 
93 //=======================================================================
94 bool SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
95 {
96   const LightApp_SVTKDataOwner* owner =
97     dynamic_cast<const LightApp_SVTKDataOwner*> ( ow );
98   if( owner ) {
99     myActors.append( dynamic_cast<SMESH_Actor*>( owner->GetActor() ) );
100   }
101   else if ( ow ) { // SVTK selection disabled
102     QString entry = ow->entry();
103     myActors.append( SMESH::FindActorByEntry( entry.toStdString().c_str() ));
104   }
105   else {
106     myActors.append( 0 );
107   }
108   return true;
109 }
110
111 //=======================================================================
112 //function : parameter
113 //purpose  : 
114 //=======================================================================
115 QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
116 {
117   QVariant val;
118   if      ( p=="client" )               val = QVariant( LightApp_Selection::parameter( p ) );
119   else if ( p=="type" )                 val = QVariant( myTypes[ind] );
120   else if ( p=="elemTypes" )            val = QVariant( elemTypes( ind ) );
121   else if ( p=="isAutoColor" )          val = QVariant( isAutoColor( ind ) );
122   else if ( p=="numberOfNodes" )        val = QVariant( numberOfNodes( ind ) );
123   else if ( p=="dim" )                  val = QVariant( dim( ind ) );
124   else if ( p=="labeledTypes" )         val = QVariant( labeledTypes( ind ) );
125   else if ( p=="shrinkMode" )           val = QVariant( shrinkMode( ind ) );
126   else if ( p=="entityMode" )           val = QVariant( entityMode( ind ) );
127   else if ( p=="isNumFunctor" )         val = QVariant( isNumFunctor( ind ) );
128   else if ( p=="displayMode" )          val = QVariant( displayMode( ind ) );
129   else if ( p=="isComputable" )         val = QVariant( isComputable( ind ) );
130   else if ( p=="isPreComputable" )      val = QVariant( isPreComputable( ind ) );
131   else if ( p=="hasGeomReference" )     val = QVariant( hasGeomReference( ind ) );
132   else if ( p=="isEditableHyp" )        val = QVariant( isEditableHyp( ind ) );
133   else if ( p=="isImported" )           val = QVariant( isImported( ind ) );
134   else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
135   else if ( p=="groupType" )            val = QVariant( groupType( ind ) );
136   else if ( p=="quadratic2DMode")       val = QVariant( quadratic2DMode( ind ) );
137   else if ( p=="isDistributionVisible") val = QVariant( isDistributionVisible( ind ) );
138   else if ( p=="isScalarBarVisible")    val = QVariant( isScalarBarVisible( ind ) );
139   else if ( p=="hasChildren")           val = QVariant( hasChildren( ind ) );
140   else if ( p=="nbChildren")            val = QVariant( nbChildren( ind ) );
141   else if ( p=="isContainer")           val = QVariant( isContainer( ind ) );
142
143   if ( val.isValid() )
144     return val;
145   else
146     return LightApp_Selection::parameter( ind, p );
147 }
148
149 //=======================================================================
150 //function : parameter
151 //purpose  :
152 //=======================================================================
153 QVariant SMESHGUI_Selection::parameter( const QString& p ) const
154 {
155   QVariant val;
156   if ( p=="controlMode" ) val = QVariant( controlMode() );
157
158   if ( val.isValid() )
159     return val;
160   else
161     return LightApp_Selection::parameter( p );
162 }
163
164 //=======================================================================
165 //function : getVtkOwner
166 //purpose  : 
167 //=======================================================================
168
169 SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const
170 {
171   if( ind >= 0 && ind < count() )
172     return myActors.isEmpty() ? 0 : myActors.at( ind );
173   else
174     return 0;
175 }
176
177 //=======================================================================
178 //function : elemTypes
179 //purpose  : may return {'Elem0d' 'Edge' 'Face' 'Volume' 'BallElem'} at most
180 //=======================================================================
181
182 QList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
183 {
184   QList<QVariant> types;
185   SMESH_Actor* actor = getActor( ind );
186   if ( actor ) {
187     TVisualObjPtr object = actor->GetObject();
188     if ( object ) {
189       if ( object->GetNbEntities( SMDSAbs_0DElement )) types.append( "Elem0d" );
190       if ( object->GetNbEntities( SMDSAbs_Ball ))      types.append( "BallElem" );
191       if ( object->GetNbEntities( SMDSAbs_Edge ))      types.append( "Edge" );
192       if ( object->GetNbEntities( SMDSAbs_Face ))      types.append( "Face" );
193       if ( object->GetNbEntities( SMDSAbs_Volume ))    types.append( "Volume" );
194     }
195   }
196   return types;
197 }
198
199 //=======================================================================
200 //function : labeledTypes
201 //purpose  : may return {'Point' 'Cell'} at most
202 //=======================================================================
203
204 QList<QVariant> SMESHGUI_Selection::labeledTypes( int ind ) const
205 {
206   QList<QVariant> types;
207   SMESH_Actor* actor = getActor( ind );
208   if ( actor ) {
209     if ( actor->GetPointsLabeled()) types.append( "Point" );
210     if ( actor->GetCellsLabeled())  types.append( "Cell" );
211   }
212   return types;
213 }
214
215 //=======================================================================
216 //function : displayMode
217 //purpose  : return SMESH_Actor::EReperesent
218 //=======================================================================
219
220 QString SMESHGUI_Selection::displayMode( int ind ) const
221 {
222   SMESH_Actor* actor = getActor( ind );
223   if ( actor ) {
224     switch( actor->GetRepresentation() ) {
225     case SMESH_Actor::eEdge:    return "eEdge";
226     case SMESH_Actor::eSurface: return "eSurface";
227     case SMESH_Actor::ePoint:   return "ePoint";
228     default: break;
229     }
230   }
231   return "Unknown";
232 }
233
234
235 //=======================================================================
236 //function : quadratic2DMode
237 //purpose  : return SMESH_Actor::EQuadratic2DRepresentation
238 //=======================================================================
239 QString SMESHGUI_Selection::quadratic2DMode( int ind ) const
240 {
241   SMESH_Actor* actor = getActor( ind );
242   if ( actor ) {
243     switch( actor->GetQuadratic2DRepresentation() ) {
244     case SMESH_Actor::eLines: return "eLines";
245     case SMESH_Actor::eArcs:  return "eArcs";
246     default: break;
247     }
248   }
249   return "Unknown";
250 }
251
252 //=======================================================================
253 //function : isDistributionVisible
254 //purpose  : Visible/Invisible distribution of the ScalarBar Actor
255 //=======================================================================
256
257 bool SMESHGUI_Selection::isDistributionVisible(int ind) const {
258   SMESH_Actor* actor = getActor( ind );
259   return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetDistributionVisibility());
260
261
262 //=======================================================================
263 //function : isScalarBarVisible
264 //purpose  : Visible/Invisible Scalar Bar
265 //=======================================================================
266
267 bool SMESHGUI_Selection::isScalarBarVisible(int ind) const {
268   SMESH_Actor* actor = getActor( ind );
269   return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetVisibility());
270 }
271
272 //=======================================================================
273 //function : shrinkMode
274 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
275 //=======================================================================
276
277 QString SMESHGUI_Selection::shrinkMode( int ind ) const
278 {
279   SMESH_Actor* actor = getActor( ind );
280   if ( actor && actor->IsShrunkable() ) {
281     return actor->IsShrunk() ? "IsShrunk" : "IsNotShrunk";
282   }
283   return "IsNotShrinkable";
284 }
285
286 //=======================================================================
287 //function : entityMode
288 //purpose  : may return {'Elem0d' 'Edge' 'Face' 'Volume' 'BallElem' } at most
289 //=======================================================================
290
291 QList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
292 {
293   QList<QVariant> types;
294   SMESH_Actor* actor = getActor( ind );
295   if ( actor ) {
296     unsigned int aMode = actor->GetEntityMode();
297     if ( aMode & SMESH_Actor::eVolumes    ) types.append( "Volume" );
298     if ( aMode & SMESH_Actor::eFaces      ) types.append( "Face"   );
299     if ( aMode & SMESH_Actor::eEdges      ) types.append( "Edge"   );
300     if ( aMode & SMESH_Actor::e0DElements ) types.append( "Elem0d" );
301     if ( aMode & SMESH_Actor::eBallElem )   types.append( "BallElem" );
302   }
303   return types;
304 }
305
306 //=======================================================================
307 //function : controlMode
308 //purpose  : return SMESH_Actor::eControl
309 //=======================================================================
310
311 QString SMESHGUI_Selection::controlMode( int ind ) const
312 {
313   SMESH_Actor* actor = getActor( ind );
314   QString mode = "eNone";
315   if ( actor ) {
316     switch( actor->GetControlMode() ) {
317     case SMESH_Actor::eLength:                mode = "eLength";                break;
318     case SMESH_Actor::eLength2D:              mode = "eLength2D";              break;
319     case SMESH_Actor::eFreeEdges:             mode = "eFreeEdges";             break;
320     case SMESH_Actor::eFreeNodes:             mode = "eFreeNodes";             break;
321     case SMESH_Actor::eFreeBorders:           mode = "eFreeBorders";           break;
322     case SMESH_Actor::eFreeFaces:             mode = "eFreeFaces";             break;
323     case SMESH_Actor::eMultiConnection:       mode = "eMultiConnection";       break;
324     case SMESH_Actor::eMultiConnection2D:     mode = "eMultiConnection2D";     break;
325     case SMESH_Actor::eArea:                  mode = "eArea";                  break;
326     case SMESH_Actor::eVolume3D:              mode = "eVolume3D";              break;
327     case SMESH_Actor::eMaxElementLength2D:    mode = "eMaxElementLength2D";    break;
328     case SMESH_Actor::eMaxElementLength3D:    mode = "eMaxElementLength3D";    break;
329     case SMESH_Actor::eTaper:                 mode = "eTaper";                 break;
330     case SMESH_Actor::eAspectRatio:           mode = "eAspectRatio";           break;
331     case SMESH_Actor::eAspectRatio3D:         mode = "eAspectRatio3D";         break;
332     case SMESH_Actor::eMinimumAngle:          mode = "eMinimumAngle";          break;
333     case SMESH_Actor::eWarping:               mode = "eWarping";               break;
334     case SMESH_Actor::eSkew:                  mode = "eSkew";                  break;
335     case SMESH_Actor::eBareBorderFace:        mode = "eBareBorderFace";        break;
336     case SMESH_Actor::eBareBorderVolume:      mode = "eBareBorderVolume";      break;
337     case SMESH_Actor::eOverConstrainedFace:   mode = "eOverConstrainedFace";   break;
338     case SMESH_Actor::eOverConstrainedVolume: mode = "eOverConstrainedVolume"; break;
339     case SMESH_Actor::eCoincidentNodes:       mode = "eCoincidentNodes";       break;
340     case SMESH_Actor::eCoincidentElems1D:     mode = "eCoincidentElems1D";     break;
341     case SMESH_Actor::eCoincidentElems2D:     mode = "eCoincidentElems2D";     break;
342     case SMESH_Actor::eCoincidentElems3D:     mode = "eCoincidentElems3D";     break;
343     default:break;
344     }
345   }
346   return mode;
347 }
348
349 //=======================================================================
350 //function : controlMode
351 //purpose  : gets global control mode; return SMESH_Actor::eControl
352 //=======================================================================
353 QString SMESHGUI_Selection::controlMode() const
354 {
355   if( myControls.count() > 0 ) {
356     QString mode = myControls[0];
357     for( int ind = 1; ind < myControls.count(); ind++ ) {
358       if( mode != myControls[ind] )
359         return "eMixed"; // different controls used for different actors
360     }
361     return mode;
362   }
363   return "eNone";
364 }
365
366 bool SMESHGUI_Selection::isNumFunctor( int ind ) const
367 {
368   bool result = false;
369   SMESH_Actor* actor = getActor( ind );
370   if ( actor ) {
371     switch( actor->GetControlMode() ) {
372     case SMESH_Actor::eLength:
373     case SMESH_Actor::eLength2D:
374     case SMESH_Actor::eMultiConnection:
375     case SMESH_Actor::eMultiConnection2D:
376     case SMESH_Actor::eArea:
377     case SMESH_Actor::eVolume3D:
378     case SMESH_Actor::eMaxElementLength2D:
379     case SMESH_Actor::eMaxElementLength3D:
380     case SMESH_Actor::eTaper:
381     case SMESH_Actor::eAspectRatio:
382     case SMESH_Actor::eAspectRatio3D:
383     case SMESH_Actor::eMinimumAngle:
384     case SMESH_Actor::eWarping:
385     case SMESH_Actor::eSkew:
386       result = true;
387       break;
388     default:
389       break;
390     }
391   }
392   return result;
393 }
394
395 //=======================================================================
396 //function : facesOrientationMode
397 //purpose  : 
398 //=======================================================================
399
400 QString SMESHGUI_Selection::facesOrientationMode( int ind ) const
401 {
402   SMESH_Actor* actor = getActor( ind );
403   if ( actor ) {
404     return actor->GetFacesOriented() ? "IsOriented" : "IsNotOriented";
405   }
406   return "Unknown";
407 }
408
409 //=======================================================================
410 //function : isAutoColor
411 //purpose  : 
412 //=======================================================================
413
414 bool SMESHGUI_Selection::isAutoColor( int ind ) const
415 {
416   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
417   {
418     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
419     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
420
421     if ( !CORBA::is_nil( obj ) ) {
422       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
423       if ( !CORBA::is_nil( mesh ) )
424         return mesh->GetAutoColor();
425     }
426   }
427   return false;
428 }
429
430 //=======================================================================
431 //function : numberOfNodes
432 //purpose  : this method is actually used to check if an object is empty or not
433 //=======================================================================
434
435 int SMESHGUI_Selection::numberOfNodes( int ind ) const
436 {
437   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
438   {
439     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
440     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
441
442     if ( !CORBA::is_nil( obj ) ) {
443       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
444       if ( !CORBA::is_nil( mesh ) )
445         return mesh->NbNodes();
446       SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
447       if ( !CORBA::is_nil( aSubMeshObj ) )
448         return aSubMeshObj->GetNumberOfNodes(true);
449       SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
450       if ( !CORBA::is_nil( aGroupObj ) )
451         return aGroupObj->IsEmpty() ? 0 : 1; // aGroupObj->Size();
452     }
453   }
454   return 0;
455 }
456
457 //================================================================================
458 /*!
459  * \brief return dimension of elements of the selected object
460  *
461  *  \retval int - 0 for 0D elements, -1 for an empty object (the rest as usual)
462  */
463 //================================================================================
464
465 int SMESHGUI_Selection::dim( int ind ) const
466 {
467   int dim = -1;
468   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
469   {
470     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
471     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
472
473     if ( !CORBA::is_nil( obj ) ) {
474       SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( obj );
475       if ( !CORBA::is_nil( idSrc ) )
476       {
477         SMESH::array_of_ElementType_var types = idSrc->GetTypes();
478         for ( size_t i = 0; i < types->length(); ++ i) {
479           switch ( types[i] ) {
480           case SMESH::EDGE  : dim = std::max( dim, 1 ); break;
481           case SMESH::FACE  : dim = std::max( dim, 2 ); break;
482           case SMESH::VOLUME: dim = std::max( dim, 3 ); break;
483           case SMESH::ELEM0D: dim = std::max( dim, 0 ); break;
484           case SMESH::BALL  : dim = std::max( dim, 0 ); break;
485           default: break;
486           }
487         }
488       }
489     }
490   }
491   return dim;
492 }
493
494 //=======================================================================
495 //function : isComputable
496 //purpose  : return true for a ready-to-compute mesh
497 //=======================================================================
498
499 bool SMESHGUI_Selection::isComputable( int ind ) const
500 {
501   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
502   {
503     QMap<int,int> modeMap;
504     _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
505     SMESHGUI_PrecomputeOp::getAssignedAlgos( so, modeMap );
506     return modeMap.size() > 0;
507   }
508   return false;
509 }
510
511 //=======================================================================
512 //function : isPreComputable
513 //purpose  : returns true for a mesh with algorithms
514 //=======================================================================
515
516 bool SMESHGUI_Selection::isPreComputable( int ind ) const
517 {
518   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
519   {
520     int maxDim = dim( ind );
521     if ( maxDim < 2 ) // we can preview 1D or 2D
522     {
523       QMap<int,int> modeMap;
524       _PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
525       SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap );
526       if ( modeMap.size() > 1 )
527         return (( modeMap.contains( SMESH::DIM_3D )) ||
528                 ( modeMap.contains( SMESH::DIM_2D ) && maxDim < 1 ));
529     }
530   }
531   return false;
532 }
533
534 //=======================================================================
535 //function : hasGeomReference
536 //purpose  : returns true for a mesh or sub-mesh on geometry
537 //=======================================================================
538
539 bool SMESHGUI_Selection::hasGeomReference( int ind ) const
540 {
541   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
542   {
543     _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
544     GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
545     return !shape->_is_nil();
546   }
547   return false;
548 }
549
550 //=======================================================================
551 //function : isEditableHyp
552 //purpose  : 
553 //=======================================================================
554
555 bool SMESHGUI_Selection::isEditableHyp( int ind ) const
556 {
557   bool isEditable = true;
558   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Hypothesis" )
559   {
560     _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
561     SMESH::SMESH_Hypothesis_var hyp = SMESH::SObjectToInterface<SMESH::SMESH_Hypothesis>( so );
562     if ( !hyp->_is_nil() )
563     {
564       isEditable = hyp->HasParameters();
565     }
566   }
567   return isEditable;
568 }
569
570 //=======================================================================
571 //function : isVisible
572 //purpose  : 
573 //=======================================================================
574
575 bool SMESHGUI_Selection::isVisible( int ind ) const
576 {
577   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
578   {
579     SMESH_Actor* actor = SMESH::FindActorByEntry( entry( ind ).toLatin1().data() );
580     if ( actor && actor->hasIO() ) {
581       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() )
582         return aViewWindow->isVisible( actor->getIO() );
583     }
584   }
585   return false;
586 }
587
588 //=======================================================================
589 //function : hasChildren
590 //purpose  : 
591 //=======================================================================
592
593 bool SMESHGUI_Selection::hasChildren( int ind ) const
594 {
595   if ( ind >= 0 )
596   {
597     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
598     if ( sobj ) 
599       return SMESH::GetActiveStudyDocument()->GetUseCaseBuilder()->HasChildren( sobj );
600   }
601   return false;
602 }
603
604 //=======================================================================
605 //function : hasChildren
606 //purpose  : 
607 //=======================================================================
608
609 int SMESHGUI_Selection::nbChildren( int ind ) const
610 {
611   int nb = 0;
612   if ( ind >= 0 )
613   {
614     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
615     if ( sobj && sobj->GetStudy()->GetUseCaseBuilder()->IsUseCaseNode( sobj ) ) {
616       _PTR(UseCaseIterator) it = sobj->GetStudy()->GetUseCaseBuilder()->GetUseCaseIterator( sobj ); 
617       for ( it->Init( false ); it->More(); it->Next() ) nb++;
618     }
619   }
620   return nb;
621 }
622
623 //=======================================================================
624 //function : isContainer
625 //purpose  : 
626 //=======================================================================
627
628 bool SMESHGUI_Selection::isContainer( int ind ) const
629 {
630   return ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Unknown";
631 }
632
633 //=======================================================================
634 //function : type
635 //purpose  : 
636 //=======================================================================
637
638 int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
639 {
640   int res = -1;
641   _PTR(SObject) obj = study->FindObjectID( entry.toLatin1().data() );
642   if ( obj ) {
643     _PTR(SObject) ref;
644     if ( obj->ReferencedObject( ref ) )
645       obj = ref;
646
647     _PTR(SObject) objFather = obj->GetFather();
648     _PTR(SComponent) objComponent = obj->GetFatherComponent();
649
650     if ( objComponent->ComponentDataType() == "SMESH" ) {
651       if ( objComponent->GetIOR() == obj->GetIOR() ) {
652         res = SMESH::COMPONENT;
653       }
654       else {
655         int aLevel = obj->Depth() - objComponent->Depth(),
656           aFTag = objFather->Tag(),
657           anOTag = obj->Tag();
658
659         switch ( aLevel )
660         {
661         case 1:
662           if ( anOTag >= SMESH::Tag_FirstMeshRoot )
663             res = SMESH::MESH;
664           break;
665         case 2:
666           switch ( aFTag )
667           {
668           case SMESH::Tag_HypothesisRoot: res = SMESH::HYPOTHESIS; break;
669           case SMESH::Tag_AlgorithmsRoot: res = SMESH::ALGORITHM;  break;
670           default: break;
671           }
672           break;
673         case 3:
674           switch ( aFTag )
675           {
676           case SMESH::Tag_SubMeshOnVertex:   res = SMESH::SUBMESH_VERTEX;   break;
677           case SMESH::Tag_SubMeshOnEdge:     res = SMESH::SUBMESH_EDGE;     break;
678           case SMESH::Tag_SubMeshOnFace:     res = SMESH::SUBMESH_FACE;     break;
679           case SMESH::Tag_SubMeshOnSolid:    res = SMESH::SUBMESH_SOLID;    break;
680           case SMESH::Tag_SubMeshOnCompound: res = SMESH::SUBMESH_COMPOUND; break;
681           default:
682             if ( aFTag >= SMESH::Tag_FirstGroup) res = SMESH::GROUP;
683             else                                 res = SMESH::SUBMESH;
684             break;
685           }
686           break;
687         }
688       }
689     }
690   }
691   return res;
692 }
693
694 //=======================================================================
695 //function : typeName
696 //purpose  : 
697 //=======================================================================
698
699 QString SMESHGUI_Selection::typeName( const int t )
700 {
701   QString res = "Unknown";
702   switch( t )
703   {
704   case SMESH::HYPOTHESIS:
705     res = "Hypothesis"; break;
706   case SMESH::ALGORITHM:
707     res = "Algorithm"; break;
708   case SMESH::MESH:
709     res = "Mesh"; break;
710   case SMESH::SUBMESH:
711     res = "SubMesh"; break;
712   case SMESH::MESHorSUBMESH:
713     res = "Mesh or submesh"; break;
714   case SMESH::SUBMESH_VERTEX:
715     res = "Mesh vertex"; break;
716   case SMESH::SUBMESH_EDGE:
717     res = "Mesh edge"; break;
718   case SMESH::SUBMESH_FACE:
719     res = "Mesh face"; break;
720   case SMESH::SUBMESH_SOLID:
721     res = "Mesh solid"; break;
722   case SMESH::SUBMESH_COMPOUND:
723     res = "Mesh compound"; break;
724   case SMESH::GROUP:
725     res = "Group"; break;
726   case SMESH::COMPONENT:
727     res = "Component"; break;
728   default:
729      break;
730   }
731   return res;
732 }
733
734 bool SMESHGUI_Selection::isImported( const int ind ) const
735 {
736   bool res = false;
737   _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().constData() );
738   if ( sobj )
739   {
740     SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( sobj ) );
741     if( !aMesh->_is_nil() )
742     {
743       SMESH::MedFileInfo_var inf = aMesh->GetMEDFileInfo();
744       res = strlen( (char*)inf->fileName ) > 0;
745     }
746   }
747   return res;
748 }
749
750 //=======================================================================
751 //function : groupType
752 //purpose  : 
753 //=======================================================================
754
755 QString SMESHGUI_Selection::groupType( int ind ) const
756 {
757   _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().constData() );
758   if ( sobj )
759   {
760     SMESH::SMESH_Group_var g = SMESH::SObjectToInterface<SMESH::SMESH_Group>( sobj );
761     if ( !CORBA::is_nil( g ) )
762       return "Group";
763     SMESH::SMESH_GroupOnGeom_var gog = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnGeom>( sobj );
764     if( !CORBA::is_nil( gog ) )
765       return "GroupOnGeom";
766     SMESH::SMESH_GroupOnFilter_var gof = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnFilter>( sobj );
767     if ( !CORBA::is_nil( gof ) )
768       return "GroupOnFilter";
769   }
770   return "";
771 }