Salome HOME
Fix for problem: Preferences-Mesh-General tab: Display modes ?Nodes? and ?Shrink...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Selection.cxx
1
2 #include "SMESHGUI_Selection.h"
3 #include "SMESHGUI_Utils.h"
4 #include "SMESHGUI_VTKUtils.h"
5 #include "SMESHGUI_MeshUtils.h"
6 #include "SMESHGUI_GEOMGenUtils.h"
7
8 #include "SMESH_Type.h"
9 #include "SMESH_Actor.h"
10
11 #include "SalomeApp_SelectionMgr.h"
12 #include "SalomeApp_Study.h"
13 #include "SalomeApp_VTKSelector.h"
14
15 #include "SUIT_Session.h"
16
17 #include "SVTK_RenderWindowInteractor.h"
18 #include "SVTK_ViewWindow.h"
19
20 #include CORBA_SERVER_HEADER(SMESH_Mesh)
21 #include CORBA_SERVER_HEADER(SMESH_Group)
22
23 //=======================================================================
24 //function : SMESHGUI_Selection
25 //purpose  : 
26 //=======================================================================
27 SMESHGUI_Selection::SMESHGUI_Selection()
28 : SalomeApp_Selection()
29 {
30 }
31
32 //=======================================================================
33 //function : ~SMESHGUI_Selection
34 //purpose  : 
35 //=======================================================================
36 SMESHGUI_Selection::~SMESHGUI_Selection()
37 {
38 }
39
40 //=======================================================================
41 //function : init
42 //purpose  : 
43 //=======================================================================
44 void SMESHGUI_Selection::init( const QString& client, SalomeApp_SelectionMgr* mgr )
45 {
46   SalomeApp_Selection::init( client, mgr );
47
48   if( mgr && study() )
49   {
50     _PTR(Study) aStudy = study()->studyDS();
51
52     SUIT_DataOwnerPtrList sel;
53     mgr->selected( sel, client );
54     myDataOwners = sel;
55     SUIT_DataOwnerPtrList::const_iterator anIt = sel.begin(),
56                                           aLast = sel.end();
57     for( ; anIt!=aLast; anIt++ )
58     {
59       SUIT_DataOwner* owner = ( SUIT_DataOwner* )( (*anIt ).get() );
60       SalomeApp_DataOwner* sowner = dynamic_cast<SalomeApp_DataOwner*>( owner );
61       if( sowner )
62         myTypes.append( typeName( type( sowner, aStudy ) ) );
63       else
64         myTypes.append( "Unknown" );
65     }
66   }
67 }
68
69 //=======================================================================
70 //function : param
71 //purpose  : 
72 //=======================================================================
73 QtxValue SMESHGUI_Selection::param( const int ind, const QString& p ) const
74 {
75   QtxValue val;
76        if ( p=="client" )        val = QtxValue( globalParam( p ) );
77   else if ( p=="type" )          val = QtxValue( myTypes[ind] );
78   else if ( p=="elemTypes" )     val = QtxValue( elemTypes( ind ) );
79   else if ( p=="numberOfNodes" ) val = QtxValue( numberOfNodes( ind ) );
80   else if ( p=="labeledTypes" )  val = QtxValue( labeledTypes( ind ) );
81   else if ( p=="shrinkMode" )    val = QtxValue( shrinkMode( ind ) );
82   else if ( p=="entityMode" )    val = QtxValue( entityMode( ind ) );
83   else if ( p=="controlMode" )   val = QtxValue( controlMode( ind ) );
84   else if ( p=="displayMode" )   val = QtxValue( displayMode( ind ) );
85   else if ( p=="isComputable" )  val = QtxValue( isComputable( ind ) );
86   else if ( p=="hasReference" )  val = QtxValue( hasReference( ind ) );
87   else if ( p=="isVisible" )     val = QtxValue( isVisible( ind ) );
88
89   // printf( "--> param() : [%s] = %s (%s)\n", p.latin1(), val.toString().latin1(), val.typeName() );
90   //if ( val.type() == QVariant::List )
91   //cout << "size: " << val.toList().count() << endl;
92   return val;
93 }
94
95 //=======================================================================
96 //function : getVtkOwner
97 //purpose  : 
98 //=======================================================================
99
100 SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const
101 {
102   if ( ind >= 0 && ind < myDataOwners.count() ) {
103     const SalomeApp_SVTKDataOwner* owner = 
104       dynamic_cast<const SalomeApp_SVTKDataOwner*> ( myDataOwners[ ind ].get() );
105     if ( owner )    
106       return dynamic_cast<SMESH_Actor*>( owner->GetActor() );
107   }
108   return 0;
109 }
110
111 //=======================================================================
112 //function : elemTypes
113 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
114 //=======================================================================
115
116 QValueList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
117 {
118   QValueList<QVariant> types;
119   SMESH_Actor* actor = getActor( ind );
120   if ( actor ) {
121     TVisualObjPtr object = actor->GetObject();
122     if ( object ) {
123       if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
124       if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
125       if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
126     }
127   }
128   return types;
129 }
130
131 //=======================================================================
132 //function : labeledTypes
133 //purpose  : may return {'Point' 'Cell'} at most
134 //=======================================================================
135
136 QValueList<QVariant> SMESHGUI_Selection::labeledTypes( int ind ) const
137 {
138   QValueList<QVariant> types;
139   SMESH_Actor* actor = getActor( ind );
140   if ( actor ) {
141     if ( actor->GetPointsLabeled()) types.append( "Point" );
142     if ( actor->GetCellsLabeled()) types.append( "Cell" );
143   }
144   return types;
145 }
146
147 //=======================================================================
148 //function : displayMode
149 //purpose  : return SMESH_Actor::EReperesent
150 //=======================================================================
151
152 QString SMESHGUI_Selection::displayMode( int ind ) const
153 {
154   SMESH_Actor* actor = getActor( ind );
155   if ( actor ) {
156     switch( actor->GetRepresentation() ) {
157     case SMESH_Actor::eEdge:    return "eEdge";
158     case SMESH_Actor::eSurface: return "eSurface";
159     case SMESH_Actor::ePoint:   return "ePoint";
160     default:;
161     }
162   }
163   return "Unknown";
164 }
165
166 //=======================================================================
167 //function : shrinkMode
168 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
169 //=======================================================================
170
171 QString SMESHGUI_Selection::shrinkMode( int ind ) const
172 {
173   SMESH_Actor* actor = getActor( ind );
174   if ( actor && actor->IsShrunkable() ) {
175     if ( actor->IsShrunk() )
176       return "IsShrunk";
177     return "IsNotShrunk";
178   }
179   return "IsNotShrinkable";
180 }
181
182 //=======================================================================
183 //function : entityMode
184 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
185 //=======================================================================
186
187 QValueList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
188 {
189   QValueList<QVariant> types;
190   SMESH_Actor* actor = getActor( ind );
191   if ( actor ) {
192     unsigned int aMode = actor->GetEntityMode();
193     if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume");
194     if ( aMode & SMESH_Actor::eFaces  ) types.append( "Face"  );
195     if ( aMode & SMESH_Actor::eEdges  ) types.append( "Edge"  );
196   }
197   return types;
198 }
199
200 //=======================================================================
201 //function : controlMode
202 //purpose  : return SMESH_Actor::eControl
203 //=======================================================================
204
205 QString SMESHGUI_Selection::controlMode( int ind ) const
206 {
207   SMESH_Actor* actor = getActor( ind );
208   if ( actor ) {
209     switch( actor->GetControlMode() ) {
210     case SMESH_Actor::eLength:            return "eLength";
211     case SMESH_Actor::eLength2D:          return "eLength2D";
212     case SMESH_Actor::eFreeEdges:         return "eFreeEdges";
213     case SMESH_Actor::eFreeBorders:       return "eFreeBorders";
214     case SMESH_Actor::eMultiConnection:   return "eMultiConnection";
215     case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
216     case SMESH_Actor::eArea:              return "eArea";
217     case SMESH_Actor::eTaper:             return "eTaper";
218     case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
219     case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
220     case SMESH_Actor::eMinimumAngle:      return "eMinimumAngle";
221     case SMESH_Actor::eWarping:           return "eWarping";
222     case SMESH_Actor::eSkew:              return "eSkew";
223     default:;
224     }
225   }
226   return "eNone";
227 }
228
229 //=======================================================================
230 //function : numberOfNodes
231 //purpose  : 
232 //=======================================================================
233
234 int SMESHGUI_Selection::numberOfNodes( int ind ) const
235 {
236   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
237   {
238     CORBA::Object_var obj =
239       SMESH::DataOwnerToObject( static_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].get() ));
240     if ( ! CORBA::is_nil( obj )) {
241       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
242       if ( ! mesh->_is_nil() )
243         return mesh->NbNodes();
244       SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
245       if ( !aSubMeshObj->_is_nil() )
246         return aSubMeshObj->GetNumberOfNodes(true);
247       SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
248       if ( !aGroupObj->_is_nil() )
249         return aGroupObj->Size();
250     }
251   }
252   return 0;
253 }
254
255 //=======================================================================
256 //function : isComputable
257 //purpose  : 
258 //=======================================================================
259
260 QVariant SMESHGUI_Selection::isComputable( int ind ) const
261 {
262   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
263   {
264     Handle(SALOME_InteractiveObject) io =
265       static_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].get() )->IO();
266     if ( !io.IsNull() ) {
267       SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io) ; // m,sm,gr->m
268       if ( !mesh->_is_nil() ) {
269         _PTR(SObject) so = SMESH::FindSObject( mesh );
270         if ( so ) {
271           GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
272           return QVariant( !shape->_is_nil(), 0 );
273         }
274       }
275     }
276   }
277   return QVariant( false, 0 );
278 }
279
280 //=======================================================================
281 //function : hasReference
282 //purpose  : 
283 //=======================================================================
284
285 QVariant SMESHGUI_Selection::hasReference( int ind ) const
286 {
287   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
288   {
289     SalomeApp_DataOwner* owner = dynamic_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].operator->() );
290     if( owner )
291     {
292       _PTR(SObject) obj ( study()->studyDS()->FindObjectID( owner->entry().latin1() ) ), ref;
293       return QVariant( obj->ReferencedObject( ref ), 0 );
294     }
295   }
296   return QVariant( false, 0 );
297 }
298
299 //=======================================================================
300 //function : isVisible
301 //purpose  : 
302 //=======================================================================
303
304 QVariant SMESHGUI_Selection::isVisible( int ind ) const
305 {
306   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
307   {
308     QString entry = static_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].get() )->entry();
309     SMESH_Actor* actor = SMESH::FindActorByEntry( entry.latin1() );
310     if ( actor && actor->hasIO() ) {
311       SVTK_RenderWindowInteractor* renderInter = SMESH::GetCurrentVtkView()->getRWInteractor();
312       return QVariant( renderInter->isVisible( actor->getIO() ), 0 );
313     }
314   }
315   return QVariant( false, 0 );
316 }
317
318
319 //=======================================================================
320 //function : type
321 //purpose  :
322 //=======================================================================
323 int SMESHGUI_Selection::type( SalomeApp_DataOwner* owner, _PTR(Study) study )
324 {
325   return type( owner->entry(), study );
326 }
327
328 //=======================================================================
329 //function : type
330 //purpose  : 
331 //=======================================================================
332
333 int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
334 {
335   _PTR(SObject) obj (study->FindObjectID(entry.latin1()));
336   if( !obj )
337     return -1;
338
339   _PTR(SObject) ref;
340   if( obj->ReferencedObject( ref ) )
341     obj = ref;
342
343   _PTR(SObject) objFather = obj->GetFather();
344   _PTR(SComponent) objComponent = obj->GetFatherComponent();
345
346   if( objComponent->ComponentDataType()!="SMESH" )
347     return -1;
348
349   int aLevel = obj->Depth() - objComponent->Depth(),
350       aFTag = objFather->Tag(),
351       anOTag = obj->Tag(),
352       res = -1;
353
354   switch( aLevel )
355   {
356   case 1:
357     if( anOTag>=3 )
358       res = MESH;
359     break;
360   case 2:
361     switch( aFTag )
362     {
363     case 1:
364       res = HYPOTHESIS;
365       break;
366     case 2:
367       res = ALGORITHM;
368       break;
369     }
370     break;
371   case 3:
372     switch( aFTag )
373     {
374     case 4:
375       res = SUBMESH_VERTEX;
376       break;
377     case 5:
378       res = SUBMESH_EDGE;
379       break;
380     case 7:
381       res = SUBMESH_FACE;
382       break;
383     case 9:
384       res = SUBMESH_SOLID;
385       break;
386     case 10:
387       res = SUBMESH_COMPOUND;
388       break;
389     }
390     if( aFTag>10 )
391       res = GROUP;
392
393     break;
394   }
395
396   return res;
397 }
398
399 //=======================================================================
400 //function : typeName
401 //purpose  : 
402 //=======================================================================
403
404 QString SMESHGUI_Selection::typeName( const int t )
405 {
406   switch( t )
407   {
408   case HYPOTHESIS:
409     return "Hypothesis";
410   case ALGORITHM:
411     return "Algorithm";
412   case MESH:
413     return "Mesh";
414   case SUBMESH:
415     return "SubMesh";
416   case MESHorSUBMESH:
417     return "Mesh or submesh";
418   case SUBMESH_VERTEX:
419     return "Mesh vertex";
420   case SUBMESH_EDGE:
421     return "Mesh edge";
422   case SUBMESH_FACE:
423     return "Mesh face";
424   case SUBMESH_SOLID:
425     return "Mesh solid";
426   case SUBMESH_COMPOUND:
427     return "Mesh compound";
428   case GROUP:
429     return "Group";
430   default:
431     return "Unknown";
432   }
433 }