Salome HOME
Implementation of NPAL13504 improvement.
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Selection.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20
21 #include "SMESHGUI_Selection.h"
22 #include "SMESHGUI_Utils.h"
23 #include "SMESHGUI_VTKUtils.h"
24 #include "SMESHGUI_MeshUtils.h"
25 #include "SMESHGUI_GEOMGenUtils.h"
26
27 #include "SMESH_Type.h"
28 #include "SMESH_Actor.h"
29
30 #include "LightApp_SelectionMgr.h"
31 #include "SalomeApp_Study.h"
32 #include "LightApp_VTKSelector.h"
33
34 #include "SUIT_Session.h"
35
36 #include "SVTK_RenderWindowInteractor.h"
37 #include "SVTK_ViewWindow.h"
38
39 #include CORBA_SERVER_HEADER(SMESH_Mesh)
40 #include CORBA_SERVER_HEADER(SMESH_Group)
41
42 //=======================================================================
43 //function : SMESHGUI_Selection
44 //purpose  : 
45 //=======================================================================
46 SMESHGUI_Selection::SMESHGUI_Selection()
47 : LightApp_Selection()
48 {
49 }
50
51 //=======================================================================
52 //function : ~SMESHGUI_Selection
53 //purpose  : 
54 //=======================================================================
55 SMESHGUI_Selection::~SMESHGUI_Selection()
56 {
57 }
58
59 //=======================================================================
60 //function : init
61 //purpose  : 
62 //=======================================================================
63 void SMESHGUI_Selection::init( const QString& client, LightApp_SelectionMgr* mgr )
64 {
65   LightApp_Selection::init( client, mgr );
66
67   if( mgr && study() )
68   {
69     SalomeApp_Study* aSStudy = dynamic_cast<SalomeApp_Study*>(study());
70     if (!aSStudy)
71       return;
72     _PTR(Study) aStudy = aSStudy->studyDS();
73
74     for( int i=0, n=count(); i<n; i++ )
75       myTypes.append( typeName( type( entry( i ), aStudy ) ) );
76   }
77 }
78
79 //=======================================================================
80 //function : processOwner
81 //purpose  : 
82 //=======================================================================
83 void SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
84 {
85   const LightApp_SVTKDataOwner* owner = 
86     dynamic_cast<const LightApp_SVTKDataOwner*> ( ow );
87   if( owner )
88     myActors.append( dynamic_cast<SMESH_Actor*>( owner->GetActor() ) );
89   else
90     myActors.append( 0 );
91 }
92
93 //=======================================================================
94 //function : param
95 //purpose  : 
96 //=======================================================================
97 QtxValue SMESHGUI_Selection::param( const int ind, const QString& p ) const
98 {
99   QtxValue val;
100        if ( p=="client" )        val = QtxValue( globalParam( p ) );
101   else if ( p=="type" )          val = QtxValue( myTypes[ind] );
102   else if ( p=="elemTypes" )     val = QtxValue( elemTypes( ind ) );
103   else if ( p=="numberOfNodes" ) val = QtxValue( numberOfNodes( ind ) );
104   else if ( p=="labeledTypes" )  val = QtxValue( labeledTypes( ind ) );
105   else if ( p=="shrinkMode" )    val = QtxValue( shrinkMode( ind ) );
106   else if ( p=="entityMode" )    val = QtxValue( entityMode( ind ) );
107   else if ( p=="controlMode" )   val = QtxValue( controlMode( ind ) );
108   else if ( p=="displayMode" )   val = QtxValue( displayMode( ind ) );
109   else if ( p=="isComputable" )  val = QtxValue( isComputable( ind ) );
110   else if ( p=="hasReference" )  val = QtxValue( hasReference( ind ) );
111 //  else if ( p=="isVisible" )     val = QtxValue( isVisible( ind ) );
112
113        // printf( "--> param() : [%s] = %s (%s)\n", p.latin1(), val.toString().latin1(), val.typeName() );
114   //if ( val.type() == QVariant::List )
115   //cout << "size: " << val.toList().count() << endl;
116
117   if( val.isValid() )
118     return val;
119   else
120     return LightApp_Selection::param( ind, p );
121 }
122
123 //=======================================================================
124 //function : getVtkOwner
125 //purpose  : 
126 //=======================================================================
127
128 SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const
129 {
130   if( ind >= 0 && ind < count() )
131     return ((QPtrList<SMESH_Actor>&)myActors).at( ind );
132   else
133     return 0;
134 }
135
136 //=======================================================================
137 //function : elemTypes
138 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
139 //=======================================================================
140
141 QValueList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
142 {
143   QValueList<QVariant> types;
144   SMESH_Actor* actor = getActor( ind );
145   if ( actor ) {
146     TVisualObjPtr object = actor->GetObject();
147     if ( object ) {
148       if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
149       if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
150       if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
151     }
152   }
153   return types;
154 }
155
156 //=======================================================================
157 //function : labeledTypes
158 //purpose  : may return {'Point' 'Cell'} at most
159 //=======================================================================
160
161 QValueList<QVariant> SMESHGUI_Selection::labeledTypes( int ind ) const
162 {
163   QValueList<QVariant> types;
164   SMESH_Actor* actor = getActor( ind );
165   if ( actor ) {
166     if ( actor->GetPointsLabeled()) types.append( "Point" );
167     if ( actor->GetCellsLabeled()) types.append( "Cell" );
168   }
169   return types;
170 }
171
172 //=======================================================================
173 //function : displayMode
174 //purpose  : return SMESH_Actor::EReperesent
175 //=======================================================================
176
177 QString SMESHGUI_Selection::displayMode( int ind ) const
178 {
179   SMESH_Actor* actor = getActor( ind );
180   if ( actor ) {
181     switch( actor->GetRepresentation() ) {
182     case SMESH_Actor::eEdge:    return "eEdge";
183     case SMESH_Actor::eSurface: return "eSurface";
184     case SMESH_Actor::ePoint:   return "ePoint";
185     default:;
186     }
187   }
188   return "Unknown";
189 }
190
191 //=======================================================================
192 //function : shrinkMode
193 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
194 //=======================================================================
195
196 QString SMESHGUI_Selection::shrinkMode( int ind ) const
197 {
198   SMESH_Actor* actor = getActor( ind );
199   if ( actor && actor->IsShrunkable() ) {
200     if ( actor->IsShrunk() )
201       return "IsShrunk";
202     return "IsNotShrunk";
203   }
204   return "IsNotShrinkable";
205 }
206
207 //=======================================================================
208 //function : entityMode
209 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
210 //=======================================================================
211
212 QValueList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
213 {
214   QValueList<QVariant> types;
215   SMESH_Actor* actor = getActor( ind );
216   if ( actor ) {
217     unsigned int aMode = actor->GetEntityMode();
218     if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume");
219     if ( aMode & SMESH_Actor::eFaces  ) types.append( "Face"  );
220     if ( aMode & SMESH_Actor::eEdges  ) types.append( "Edge"  );
221   }
222   return types;
223 }
224
225 //=======================================================================
226 //function : controlMode
227 //purpose  : return SMESH_Actor::eControl
228 //=======================================================================
229
230 QString SMESHGUI_Selection::controlMode( int ind ) const
231 {
232   SMESH_Actor* actor = getActor( ind );
233   if ( actor ) {
234     switch( actor->GetControlMode() ) {
235     case SMESH_Actor::eLength:            return "eLength";
236     case SMESH_Actor::eLength2D:          return "eLength2D";
237     case SMESH_Actor::eFreeEdges:         return "eFreeEdges";
238     case SMESH_Actor::eFreeBorders:       return "eFreeBorders";
239     case SMESH_Actor::eMultiConnection:   return "eMultiConnection";
240     case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
241     case SMESH_Actor::eArea:              return "eArea";
242     case SMESH_Actor::eVolume3D:          return "eVolume3D";
243     case SMESH_Actor::eTaper:             return "eTaper";
244     case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
245     case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
246     case SMESH_Actor::eMinimumAngle:      return "eMinimumAngle";
247     case SMESH_Actor::eWarping:           return "eWarping";
248     case SMESH_Actor::eSkew:              return "eSkew";
249     default:;
250     }
251   }
252   return "eNone";
253 }
254
255 //=======================================================================
256 //function : numberOfNodes
257 //purpose  : 
258 //=======================================================================
259
260 int SMESHGUI_Selection::numberOfNodes( int ind ) const
261 {
262   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
263   {
264     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).latin1() );
265     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
266
267     if ( ! CORBA::is_nil( obj )) {
268       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
269       if ( ! mesh->_is_nil() )
270         return mesh->NbNodes();
271       SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
272       if ( !aSubMeshObj->_is_nil() )
273         return aSubMeshObj->GetNumberOfNodes(true);
274       SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
275       if ( !aGroupObj->_is_nil() )
276         return aGroupObj->Size();
277     }
278   }
279   return 0;
280 }
281
282 //=======================================================================
283 //function : isComputable
284 //purpose  : 
285 //=======================================================================
286
287 QVariant SMESHGUI_Selection::isComputable( int ind ) const
288 {
289   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
290   {
291 /*    Handle(SALOME_InteractiveObject) io =
292       static_cast<LightApp_DataOwner*>( myDataOwners[ ind ].get() )->IO();
293     if ( !io.IsNull() ) {
294       SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io) ; // m,sm,gr->m
295       if ( !mesh->_is_nil() ) {*/
296         _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).latin1() );
297         //FindSObject( mesh );
298         if ( so ) {
299           CORBA::Object_var obj = SMESH::SObjectToObject(so, SMESH::GetActiveStudyDocument());
300           if(!CORBA::is_nil(obj)){
301             SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
302             if (!mesh->_is_nil()){
303               if(mesh->HasShapeToMesh()) {
304                 GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
305                 return QVariant( !shape->_is_nil(), 0 );
306               }
307               else
308               {
309                 return QVariant(!mesh->NbFaces()==0, 0);
310               }
311             }
312             else
313             {
314               GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
315               return QVariant( !shape->_is_nil(), 0 );
316             }
317           }
318         }
319 //      }
320 //    }
321   }
322   return QVariant( false, 0 );
323 }
324
325 //=======================================================================
326 //function : hasReference
327 //purpose  : 
328 //=======================================================================
329
330 QVariant SMESHGUI_Selection::hasReference( int ind ) const
331 {
332   return QVariant( isReference( ind ), 0 );
333 }
334
335 //=======================================================================
336 //function : isVisible
337 //purpose  : 
338 //=======================================================================
339
340 QVariant SMESHGUI_Selection::isVisible( int ind ) const
341 {
342   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
343   {
344     QString ent = entry( ind );
345     SMESH_Actor* actor = SMESH::FindActorByEntry( ent.latin1() );
346     if ( actor && actor->hasIO() ) {
347       if(SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView())
348         return QVariant( aViewWindow->isVisible( actor->getIO() ), 0 );
349     }
350   }
351   return QVariant( false, 0 );
352 }
353
354 //=======================================================================
355 //function : type
356 //purpose  : 
357 //=======================================================================
358
359 int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
360 {
361   _PTR(SObject) obj (study->FindObjectID(entry.latin1()));
362   if( !obj )
363     return -1;
364
365   _PTR(SObject) ref;
366   if( obj->ReferencedObject( ref ) )
367     obj = ref;
368
369   _PTR(SObject) objFather = obj->GetFather();
370   _PTR(SComponent) objComponent = obj->GetFatherComponent();
371
372   if( objComponent->ComponentDataType()!="SMESH" )
373     return -1;
374
375   if( objComponent->GetIOR()==obj->GetIOR() )
376     return COMPONENT;
377
378   int aLevel = obj->Depth() - objComponent->Depth(),
379       aFTag = objFather->Tag(),
380       anOTag = obj->Tag(),
381       res = -1;
382
383   switch( aLevel )
384   {
385   case 1:
386     if( anOTag>=3 )
387       res = MESH;
388     break;
389   case 2:
390     switch( aFTag )
391     {
392     case 1:
393       res = HYPOTHESIS;
394       break;
395     case 2:
396       res = ALGORITHM;
397       break;
398     }
399     break;
400   case 3:
401     switch( aFTag )
402     {
403     case 4:
404       res = SUBMESH_VERTEX;
405       break;
406     case 5:
407       res = SUBMESH_EDGE;
408       break;
409     case 7:
410       res = SUBMESH_FACE;
411       break;
412     case 9:
413       res = SUBMESH_SOLID;
414       break;
415     case 10:
416       res = SUBMESH_COMPOUND;
417       break;
418     }
419     if( aFTag>10 )
420       res = GROUP;
421     else
422       res = SUBMESH;
423
424     break;
425   }
426
427   return res;
428 }
429
430 //=======================================================================
431 //function : typeName
432 //purpose  : 
433 //=======================================================================
434
435 QString SMESHGUI_Selection::typeName( const int t )
436 {
437   switch( t )
438   {
439   case HYPOTHESIS:
440     return "Hypothesis";
441   case ALGORITHM:
442     return "Algorithm";
443   case MESH:
444     return "Mesh";
445   case SUBMESH:
446     return "SubMesh";
447   case MESHorSUBMESH:
448     return "Mesh or submesh";
449   case SUBMESH_VERTEX:
450     return "Mesh vertex";
451   case SUBMESH_EDGE:
452     return "Mesh edge";
453   case SUBMESH_FACE:
454     return "Mesh face";
455   case SUBMESH_SOLID:
456     return "Mesh solid";
457   case SUBMESH_COMPOUND:
458     return "Mesh compound";
459   case GROUP:
460     return "Group";
461   case COMPONENT:
462     return "Component";
463   default:
464     return "Unknown";
465   }
466 }