Salome HOME
IPAL20992 Controls Free nodes works wrong
[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::eFreeNodes:         return "eFreeNodes";
243     case SMESH_Actor::eFreeBorders:       return "eFreeBorders";
244     case SMESH_Actor::eFreeFaces:         return "eFreeFaces";
245     case SMESH_Actor::eMultiConnection:   return "eMultiConnection";
246     case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
247     case SMESH_Actor::eArea:              return "eArea";
248     case SMESH_Actor::eVolume3D:          return "eVolume3D";
249     case SMESH_Actor::eTaper:             return "eTaper";
250     case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
251     case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
252     case SMESH_Actor::eMinimumAngle:      return "eMinimumAngle";
253     case SMESH_Actor::eWarping:           return "eWarping";
254     case SMESH_Actor::eSkew:              return "eSkew";
255     default:;
256     }
257   }
258   return "eNone";
259 }
260
261 //=======================================================================
262 //function : facesOrientationMode
263 //purpose  : 
264 //=======================================================================
265
266 QString SMESHGUI_Selection::facesOrientationMode( int ind ) const
267 {
268   SMESH_Actor* actor = getActor( ind );
269   if ( actor ) {
270     if ( actor->GetFacesOriented() )
271       return "IsOriented";
272     return "IsNotOriented";
273   }
274   return "Unknown";
275 }
276
277 //=======================================================================
278 //function : isAutoColor
279 //purpose  : 
280 //=======================================================================
281
282 bool SMESHGUI_Selection::isAutoColor( int ind ) const
283 {
284   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
285   {
286     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
287     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
288
289     if ( ! CORBA::is_nil( obj )) {
290       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
291       if ( ! mesh->_is_nil() )
292         return mesh->GetAutoColor();
293     }
294   }
295   return false;
296 }
297
298 //=======================================================================
299 //function : numberOfNodes
300 //purpose  : 
301 //=======================================================================
302
303 int SMESHGUI_Selection::numberOfNodes( int ind ) const
304 {
305   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
306   {
307     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
308     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
309
310     if ( ! CORBA::is_nil( obj )) {
311       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
312       if ( ! mesh->_is_nil() )
313         return mesh->NbNodes();
314       SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
315       if ( !aSubMeshObj->_is_nil() )
316         return aSubMeshObj->GetNumberOfNodes(true);
317       SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
318       if ( !aGroupObj->_is_nil() )
319         return aGroupObj->Size();
320     }
321   }
322   return 0;
323 }
324
325 //=======================================================================
326 //function : isComputable
327 //purpose  : 
328 //=======================================================================
329
330 QVariant SMESHGUI_Selection::isComputable( int ind ) const
331 {
332   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
333   {
334 /*    Handle(SALOME_InteractiveObject) io =
335       static_cast<LightApp_DataOwner*>( myDataOwners[ ind ].get() )->IO();
336     if ( !io.IsNull() ) {
337       SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io); // m,sm,gr->m
338       if ( !mesh->_is_nil() ) {*/
339         _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
340         //FindSObject( mesh );
341         if ( so ) {
342           CORBA::Object_var obj = SMESH::SObjectToObject(so, SMESH::GetActiveStudyDocument());
343           if(!CORBA::is_nil(obj)){
344             SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
345             if (!mesh->_is_nil()){
346               if(mesh->HasShapeToMesh()) {
347                 GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
348                 return QVariant( !shape->_is_nil() );
349               }
350               else
351               {
352                 return QVariant(!mesh->NbFaces()==0);
353               }
354             }
355             else
356             {
357               GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
358               return QVariant( !shape->_is_nil() );
359             }
360           }
361         }
362 //      }
363 //    }
364   }
365   return QVariant( false );
366 }
367
368 //=======================================================================
369 //function : hasReference
370 //purpose  : 
371 //=======================================================================
372
373 QVariant SMESHGUI_Selection::hasReference( int ind ) const
374 {
375   return QVariant( isReference( ind ) );
376 }
377
378 //=======================================================================
379 //function : isVisible
380 //purpose  : 
381 //=======================================================================
382
383 QVariant SMESHGUI_Selection::isVisible( int ind ) const
384 {
385   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
386   {
387     QString ent = entry( ind );
388     SMESH_Actor* actor = SMESH::FindActorByEntry( ent.toLatin1().data() );
389     if ( actor && actor->hasIO() ) {
390       if(SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView())
391         return QVariant( aViewWindow->isVisible( actor->getIO() ) );
392     }
393   }
394   return QVariant( false );
395 }
396
397 //=======================================================================
398 //function : type
399 //purpose  : 
400 //=======================================================================
401
402 int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
403 {
404   _PTR(SObject) obj (study->FindObjectID(entry.toLatin1().data()));
405   if( !obj )
406     return -1;
407
408   _PTR(SObject) ref;
409   if( obj->ReferencedObject( ref ) )
410     obj = ref;
411
412   _PTR(SObject) objFather = obj->GetFather();
413   _PTR(SComponent) objComponent = obj->GetFatherComponent();
414
415   if( objComponent->ComponentDataType()!="SMESH" )
416     return -1;
417
418   if( objComponent->GetIOR()==obj->GetIOR() )
419     return COMPONENT;
420
421   int aLevel = obj->Depth() - objComponent->Depth(),
422       aFTag = objFather->Tag(),
423       anOTag = obj->Tag(),
424       res = -1;
425
426   switch (aLevel)
427   {
428   case 1:
429     if (anOTag >= SMESH::Tag_FirstMeshRoot)
430       res = MESH;
431     break;
432   case 2:
433     switch (aFTag)
434     {
435     case SMESH::Tag_HypothesisRoot:
436       res = HYPOTHESIS;
437       break;
438     case SMESH::Tag_AlgorithmsRoot:
439       res = ALGORITHM;
440       break;
441     }
442     break;
443   case 3:
444     switch (aFTag)
445     {
446     case SMESH::Tag_SubMeshOnVertex:
447       res = SUBMESH_VERTEX;
448       break;
449     case SMESH::Tag_SubMeshOnEdge:
450       res = SUBMESH_EDGE;
451       break;
452     case SMESH::Tag_SubMeshOnFace:
453       res = SUBMESH_FACE;
454       break;
455     case SMESH::Tag_SubMeshOnSolid:
456       res = SUBMESH_SOLID;
457       break;
458     case SMESH::Tag_SubMeshOnCompound:
459       res = SUBMESH_COMPOUND;
460       break;
461     default:
462       if (aFTag >= SMESH::Tag_FirstGroup)
463         res = GROUP;
464       else
465         res = SUBMESH;
466     }
467     break;
468   }
469
470   return res;
471 }
472
473 //=======================================================================
474 //function : typeName
475 //purpose  : 
476 //=======================================================================
477
478 QString SMESHGUI_Selection::typeName( const int t )
479 {
480   switch( t )
481   {
482   case HYPOTHESIS:
483     return "Hypothesis";
484   case ALGORITHM:
485     return "Algorithm";
486   case MESH:
487     return "Mesh";
488   case SUBMESH:
489     return "SubMesh";
490   case MESHorSUBMESH:
491     return "Mesh or submesh";
492   case SUBMESH_VERTEX:
493     return "Mesh vertex";
494   case SUBMESH_EDGE:
495     return "Mesh edge";
496   case SUBMESH_FACE:
497     return "Mesh face";
498   case SUBMESH_SOLID:
499     return "Mesh solid";
500   case SUBMESH_COMPOUND:
501     return "Mesh compound";
502   case GROUP:
503     return "Group";
504   case COMPONENT:
505     return "Component";
506   default:
507     return "Unknown";
508   }
509 }
510
511 bool SMESHGUI_Selection::isImported( const int ind ) const
512 {
513   QString e = entry( ind );
514   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
515   bool res = false;
516   if( SO )
517   {
518     SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( SO ) );
519     if( !aMesh->_is_nil() )
520     {
521       SALOME_MED::MedFileInfo* inf = aMesh->GetMEDFileInfo();
522       res = strlen( (char*)inf->fileName ) > 0;
523     }
524   }
525   return res;
526 }
527
528 //=======================================================================
529 //function : groupType
530 //purpose  : 
531 //=======================================================================
532
533 QString SMESHGUI_Selection::groupType( int ind ) const
534 {
535   QString e = entry( ind );
536   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
537   QString type;
538   if( SO )
539   {
540     CORBA::Object_var obj = SMESH::SObjectToObject( SO );
541   
542     SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( obj );
543     SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( obj );
544     if( !aGroup->_is_nil() )
545       type = QString( "Group" );
546     else if ( !aGroupOnGeom->_is_nil() )
547       type = QString( "GroupOnGeom" );
548   }
549   return type;
550 }