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