Salome HOME
cc09a369fd13724db692f6bd4a264188788ad728
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Selection.cxx
1 //  Copyright (C) 2007-2008  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.
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 // SMESH SMESHGUI_Selection
23 // File   : SMESHGUI_Selection.cxx
24 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
25 // SMESH includes
26 //
27 #include "SMESHGUI_Selection.h"
28
29 #include "SMESHGUI_Utils.h"
30 #include "SMESHGUI_VTKUtils.h"
31 #include "SMESHGUI_GEOMGenUtils.h"
32
33 #include <SMESH_Type.h>
34 #include <SMESH_Actor.h>
35
36 // SALOME GUI includes
37 #include <SalomeApp_Study.h>
38 #include <LightApp_VTKSelector.h>
39 #include <SVTK_ViewWindow.h>
40
41 // IDL includes
42 #include <SALOMEconfig.h>
43 #include CORBA_CLIENT_HEADER(SMESH_Gen)
44 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
45 #include CORBA_CLIENT_HEADER(SMESH_Group)
46
47 //=======================================================================
48 //function : SMESHGUI_Selection
49 //purpose  : 
50 //=======================================================================
51 SMESHGUI_Selection::SMESHGUI_Selection()
52 : LightApp_Selection()
53 {
54 }
55
56 //=======================================================================
57 //function : ~SMESHGUI_Selection
58 //purpose  : 
59 //=======================================================================
60 SMESHGUI_Selection::~SMESHGUI_Selection()
61 {
62 }
63
64 //=======================================================================
65 //function : init
66 //purpose  : 
67 //=======================================================================
68 void SMESHGUI_Selection::init( const QString& client, LightApp_SelectionMgr* mgr )
69 {
70   LightApp_Selection::init( client, mgr );
71
72   if( mgr && study() )
73   {
74     SalomeApp_Study* aSStudy = dynamic_cast<SalomeApp_Study*>(study());
75     if (!aSStudy)
76       return;
77     _PTR(Study) aStudy = aSStudy->studyDS();
78
79     for( int i=0, n=count(); i<n; i++ )
80       myTypes.append( typeName( type( entry( i ), aStudy ) ) );
81   }
82 }
83
84 //=======================================================================
85 //function : processOwner
86 //purpose  : 
87 //=======================================================================
88 void SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
89 {
90   const LightApp_SVTKDataOwner* owner =
91     dynamic_cast<const LightApp_SVTKDataOwner*> ( ow );
92   if( owner )
93     myActors.append( dynamic_cast<SMESH_Actor*>( owner->GetActor() ) );
94   else
95     myActors.append( 0 );
96 }
97
98 //=======================================================================
99 //function : parameter
100 //purpose  : 
101 //=======================================================================
102 QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
103 {
104   QVariant val;
105   if      ( p=="client" )        val = QVariant( LightApp_Selection::parameter( p ) );
106   else if ( p=="type" )          val = QVariant( myTypes[ind] );
107   else if ( p=="elemTypes" )     val = QVariant( elemTypes( ind ) );
108   else if ( p=="isAutoColor" )   val = QVariant( isAutoColor( ind ) );
109   else if ( p=="numberOfNodes" ) val = QVariant( numberOfNodes( ind ) );
110   else if ( p=="labeledTypes" )  val = QVariant( labeledTypes( ind ) );
111   else if ( p=="shrinkMode" )    val = QVariant( shrinkMode( ind ) );
112   else if ( p=="entityMode" )    val = QVariant( entityMode( ind ) );
113   else if ( p=="controlMode" )   val = QVariant( controlMode( ind ) );
114   else if ( p=="displayMode" )   val = QVariant( displayMode( ind ) );
115   else if ( p=="isComputable" )  val = QVariant( isComputable( ind ) );
116   else if ( p=="hasReference" )  val = QVariant( hasReference( ind ) );
117   else if ( p=="isImported" )    val = QVariant( isImported( ind ) );
118   else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
119   else if ( p=="groupType" )     val = QVariant( groupType( ind ) );
120
121   if( val.isValid() )
122     return val;
123   else
124     return LightApp_Selection::parameter( ind, p );
125 }
126
127 //=======================================================================
128 //function : getVtkOwner
129 //purpose  : 
130 //=======================================================================
131
132 SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const
133 {
134   if( ind >= 0 && ind < count() )
135     return myActors.isEmpty() ? 0 : myActors.at( ind );
136   else
137     return 0;
138 }
139
140 //=======================================================================
141 //function : elemTypes
142 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
143 //=======================================================================
144
145 QList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
146 {
147   QList<QVariant> types;
148   SMESH_Actor* actor = getActor( ind );
149   if ( actor ) {
150     TVisualObjPtr object = actor->GetObject();
151     if ( object ) {
152       if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
153       if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
154       if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
155     }
156   }
157   return types;
158 }
159
160 //=======================================================================
161 //function : labeledTypes
162 //purpose  : may return {'Point' 'Cell'} at most
163 //=======================================================================
164
165 QList<QVariant> SMESHGUI_Selection::labeledTypes( int ind ) const
166 {
167   QList<QVariant> types;
168   SMESH_Actor* actor = getActor( ind );
169   if ( actor ) {
170     if ( actor->GetPointsLabeled()) types.append( "Point" );
171     if ( actor->GetCellsLabeled()) types.append( "Cell" );
172   }
173   return types;
174 }
175
176 //=======================================================================
177 //function : displayMode
178 //purpose  : return SMESH_Actor::EReperesent
179 //=======================================================================
180
181 QString SMESHGUI_Selection::displayMode( int ind ) const
182 {
183   SMESH_Actor* actor = getActor( ind );
184   if ( actor ) {
185     switch( actor->GetRepresentation() ) {
186     case SMESH_Actor::eEdge:    return "eEdge";
187     case SMESH_Actor::eSurface: return "eSurface";
188     case SMESH_Actor::ePoint:   return "ePoint";
189     default: break;
190     }
191   }
192   return "Unknown";
193 }
194
195 //=======================================================================
196 //function : shrinkMode
197 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
198 //=======================================================================
199
200 QString SMESHGUI_Selection::shrinkMode( int ind ) const
201 {
202   SMESH_Actor* actor = getActor( ind );
203   if ( actor && actor->IsShrunkable() ) {
204     if ( actor->IsShrunk() )
205       return "IsShrunk";
206     return "IsNotShrunk";
207   }
208   return "IsNotShrinkable";
209 }
210
211 //=======================================================================
212 //function : entityMode
213 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
214 //=======================================================================
215
216 QList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
217 {
218   QList<QVariant> types;
219   SMESH_Actor* actor = getActor( ind );
220   if ( actor ) {
221     unsigned int aMode = actor->GetEntityMode();
222     if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume");
223     if ( aMode & SMESH_Actor::eFaces  ) types.append( "Face"  );
224     if ( aMode & SMESH_Actor::eEdges  ) types.append( "Edge"  );
225   }
226   return types;
227 }
228
229 //=======================================================================
230 //function : controlMode
231 //purpose  : return SMESH_Actor::eControl
232 //=======================================================================
233
234 QString SMESHGUI_Selection::controlMode( int ind ) const
235 {
236   SMESH_Actor* actor = getActor( ind );
237   if ( actor ) {
238     switch( actor->GetControlMode() ) {
239     case SMESH_Actor::eLength:            return "eLength";
240     case SMESH_Actor::eLength2D:          return "eLength2D";
241     case SMESH_Actor::eFreeEdges:         return "eFreeEdges";
242     case SMESH_Actor::eFreeBorders:       return "eFreeBorders";
243     case SMESH_Actor::eFreeFaces:         return "eFreeFaces";
244     case SMESH_Actor::eMultiConnection:   return "eMultiConnection";
245     case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
246     case SMESH_Actor::eArea:              return "eArea";
247     case SMESH_Actor::eVolume3D:          return "eVolume3D";
248     case SMESH_Actor::eTaper:             return "eTaper";
249     case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
250     case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
251     case SMESH_Actor::eMinimumAngle:      return "eMinimumAngle";
252     case SMESH_Actor::eWarping:           return "eWarping";
253     case SMESH_Actor::eSkew:              return "eSkew";
254     default:;
255     }
256   }
257   return "eNone";
258 }
259
260 //=======================================================================
261 //function : facesOrientationMode
262 //purpose  : 
263 //=======================================================================
264
265 QString SMESHGUI_Selection::facesOrientationMode( int ind ) const
266 {
267   SMESH_Actor* actor = getActor( ind );
268   if ( actor ) {
269     if ( actor->GetFacesOriented() )
270       return "IsOriented";
271     return "IsNotOriented";
272   }
273   return "Unknown";
274 }
275
276 //=======================================================================
277 //function : isAutoColor
278 //purpose  : 
279 //=======================================================================
280
281 bool SMESHGUI_Selection::isAutoColor( int ind ) const
282 {
283   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
284   {
285     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
286     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
287
288     if ( ! CORBA::is_nil( obj )) {
289       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
290       if ( ! mesh->_is_nil() )
291         return mesh->GetAutoColor();
292     }
293   }
294   return false;
295 }
296
297 //=======================================================================
298 //function : numberOfNodes
299 //purpose  : 
300 //=======================================================================
301
302 int SMESHGUI_Selection::numberOfNodes( int ind ) const
303 {
304   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
305   {
306     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
307     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
308
309     if ( ! CORBA::is_nil( obj )) {
310       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
311       if ( ! mesh->_is_nil() )
312         return mesh->NbNodes();
313       SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
314       if ( !aSubMeshObj->_is_nil() )
315         return aSubMeshObj->GetNumberOfNodes(true);
316       SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
317       if ( !aGroupObj->_is_nil() )
318         return aGroupObj->Size();
319     }
320   }
321   return 0;
322 }
323
324 //=======================================================================
325 //function : isComputable
326 //purpose  : 
327 //=======================================================================
328
329 QVariant SMESHGUI_Selection::isComputable( int ind ) const
330 {
331   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
332   {
333 /*    Handle(SALOME_InteractiveObject) io =
334       static_cast<LightApp_DataOwner*>( myDataOwners[ ind ].get() )->IO();
335     if ( !io.IsNull() ) {
336       SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io); // m,sm,gr->m
337       if ( !mesh->_is_nil() ) {*/
338         _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
339         //FindSObject( mesh );
340         if ( so ) {
341           CORBA::Object_var obj = SMESH::SObjectToObject(so, SMESH::GetActiveStudyDocument());
342           if(!CORBA::is_nil(obj)){
343             SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
344             if (!mesh->_is_nil()){
345               if(mesh->HasShapeToMesh()) {
346                 GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
347                 return QVariant( !shape->_is_nil() );
348               }
349               else
350               {
351                 return QVariant(!mesh->NbFaces()==0);
352               }
353             }
354             else
355             {
356               GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
357               return QVariant( !shape->_is_nil() );
358             }
359           }
360         }
361 //      }
362 //    }
363   }
364   return QVariant( false );
365 }
366
367 //=======================================================================
368 //function : hasReference
369 //purpose  : 
370 //=======================================================================
371
372 QVariant SMESHGUI_Selection::hasReference( int ind ) const
373 {
374   return QVariant( isReference( ind ) );
375 }
376
377 //=======================================================================
378 //function : isVisible
379 //purpose  : 
380 //=======================================================================
381
382 QVariant SMESHGUI_Selection::isVisible( int ind ) const
383 {
384   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
385   {
386     QString ent = entry( ind );
387     SMESH_Actor* actor = SMESH::FindActorByEntry( ent.toLatin1().data() );
388     if ( actor && actor->hasIO() ) {
389       if(SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView())
390         return QVariant( aViewWindow->isVisible( actor->getIO() ) );
391     }
392   }
393   return QVariant( false );
394 }
395
396 //=======================================================================
397 //function : type
398 //purpose  : 
399 //=======================================================================
400
401 int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
402 {
403   _PTR(SObject) obj (study->FindObjectID(entry.toLatin1().data()));
404   if( !obj )
405     return -1;
406
407   _PTR(SObject) ref;
408   if( obj->ReferencedObject( ref ) )
409     obj = ref;
410
411   _PTR(SObject) objFather = obj->GetFather();
412   _PTR(SComponent) objComponent = obj->GetFatherComponent();
413
414   if( objComponent->ComponentDataType()!="SMESH" )
415     return -1;
416
417   if( objComponent->GetIOR()==obj->GetIOR() )
418     return COMPONENT;
419
420   int aLevel = obj->Depth() - objComponent->Depth(),
421       aFTag = objFather->Tag(),
422       anOTag = obj->Tag(),
423       res = -1;
424
425   switch (aLevel)
426   {
427   case 1:
428     if (anOTag >= SMESH::Tag_FirstMeshRoot)
429       res = MESH;
430     break;
431   case 2:
432     switch (aFTag)
433     {
434     case SMESH::Tag_HypothesisRoot:
435       res = HYPOTHESIS;
436       break;
437     case SMESH::Tag_AlgorithmsRoot:
438       res = ALGORITHM;
439       break;
440     }
441     break;
442   case 3:
443     switch (aFTag)
444     {
445     case SMESH::Tag_SubMeshOnVertex:
446       res = SUBMESH_VERTEX;
447       break;
448     case SMESH::Tag_SubMeshOnEdge:
449       res = SUBMESH_EDGE;
450       break;
451     case SMESH::Tag_SubMeshOnFace:
452       res = SUBMESH_FACE;
453       break;
454     case SMESH::Tag_SubMeshOnSolid:
455       res = SUBMESH_SOLID;
456       break;
457     case SMESH::Tag_SubMeshOnCompound:
458       res = SUBMESH_COMPOUND;
459       break;
460     default:
461       if (aFTag >= SMESH::Tag_FirstGroup)
462         res = GROUP;
463       else
464         res = SUBMESH;
465     }
466     break;
467   }
468
469   return res;
470 }
471
472 //=======================================================================
473 //function : typeName
474 //purpose  : 
475 //=======================================================================
476
477 QString SMESHGUI_Selection::typeName( const int t )
478 {
479   switch( t )
480   {
481   case HYPOTHESIS:
482     return "Hypothesis";
483   case ALGORITHM:
484     return "Algorithm";
485   case MESH:
486     return "Mesh";
487   case SUBMESH:
488     return "SubMesh";
489   case MESHorSUBMESH:
490     return "Mesh or submesh";
491   case SUBMESH_VERTEX:
492     return "Mesh vertex";
493   case SUBMESH_EDGE:
494     return "Mesh edge";
495   case SUBMESH_FACE:
496     return "Mesh face";
497   case SUBMESH_SOLID:
498     return "Mesh solid";
499   case SUBMESH_COMPOUND:
500     return "Mesh compound";
501   case GROUP:
502     return "Group";
503   case COMPONENT:
504     return "Component";
505   default:
506     return "Unknown";
507   }
508 }
509
510 bool SMESHGUI_Selection::isImported( const int ind ) const
511 {
512   QString e = entry( ind );
513   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
514   bool res = false;
515   if( SO )
516   {
517     SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( SO ) );
518     if( !aMesh->_is_nil() )
519     {
520       SALOME_MED::MedFileInfo* inf = aMesh->GetMEDFileInfo();
521       res = strlen( (char*)inf->fileName ) > 0;
522     }
523   }
524   return res;
525 }
526
527 //=======================================================================
528 //function : groupType
529 //purpose  : 
530 //=======================================================================
531
532 QString SMESHGUI_Selection::groupType( int ind ) const
533 {
534   QString e = entry( ind );
535   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
536   QString type;
537   if( SO )
538   {
539     CORBA::Object_var obj = SMESH::SObjectToObject( SO );
540   
541     SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( obj );
542     SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( obj );
543     if( !aGroup->_is_nil() )
544       type = QString( "Group" );
545     else if ( !aGroupOnGeom->_is_nil() )
546       type = QString( "GroupOnGeom" );
547   }
548   return type;
549 }