Salome HOME
Implementation of the issue 20115: [CEA 308] Quadratic elements visualization.
[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   else if ( p=="quadratic2DMode") val =  QVariant(quadratic2DMode(ind));
121
122   if( val.isValid() )
123     return val;
124   else
125     return LightApp_Selection::parameter( ind, p );
126 }
127
128 //=======================================================================
129 //function : getVtkOwner
130 //purpose  : 
131 //=======================================================================
132
133 SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const
134 {
135   if( ind >= 0 && ind < count() )
136     return myActors.isEmpty() ? 0 : myActors.at( ind );
137   else
138     return 0;
139 }
140
141 //=======================================================================
142 //function : elemTypes
143 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
144 //=======================================================================
145
146 QList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
147 {
148   QList<QVariant> types;
149   SMESH_Actor* actor = getActor( ind );
150   if ( actor ) {
151     TVisualObjPtr object = actor->GetObject();
152     if ( object ) {
153       if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
154       if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
155       if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
156     }
157   }
158   return types;
159 }
160
161 //=======================================================================
162 //function : labeledTypes
163 //purpose  : may return {'Point' 'Cell'} at most
164 //=======================================================================
165
166 QList<QVariant> SMESHGUI_Selection::labeledTypes( int ind ) const
167 {
168   QList<QVariant> types;
169   SMESH_Actor* actor = getActor( ind );
170   if ( actor ) {
171     if ( actor->GetPointsLabeled()) types.append( "Point" );
172     if ( actor->GetCellsLabeled()) types.append( "Cell" );
173   }
174   return types;
175 }
176
177 //=======================================================================
178 //function : displayMode
179 //purpose  : return SMESH_Actor::EReperesent
180 //=======================================================================
181
182 QString SMESHGUI_Selection::displayMode( int ind ) const
183 {
184   SMESH_Actor* actor = getActor( ind );
185   if ( actor ) {
186     switch( actor->GetRepresentation() ) {
187     case SMESH_Actor::eEdge:    return "eEdge";
188     case SMESH_Actor::eSurface: return "eSurface";
189     case SMESH_Actor::ePoint:   return "ePoint";
190     default: break;
191     }
192   }
193   return "Unknown";
194 }
195
196
197 //=======================================================================
198 //function : quadratic2DMode
199 //purpose  : return SMESH_Actor::EQuadratic2DRepresentation
200 //=======================================================================
201 QString SMESHGUI_Selection::quadratic2DMode( int ind ) const
202 {
203   SMESH_Actor* actor = getActor( ind );
204   if ( actor ) {
205     switch( actor->GetQuadratic2DRepresentation() ) {
206     case SMESH_Actor::eLines:    return "eLines";
207     case SMESH_Actor::eArcs: return "eArcs";
208     default: break;
209     }
210   }
211   return "Unknown";
212 }
213
214 //=======================================================================
215 //function : shrinkMode
216 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
217 //=======================================================================
218
219 QString SMESHGUI_Selection::shrinkMode( int ind ) const
220 {
221   SMESH_Actor* actor = getActor( ind );
222   if ( actor && actor->IsShrunkable() ) {
223     if ( actor->IsShrunk() )
224       return "IsShrunk";
225     return "IsNotShrunk";
226   }
227   return "IsNotShrinkable";
228 }
229
230 //=======================================================================
231 //function : entityMode
232 //purpose  : may return {'Edge' 'Face' 'Volume'} at most
233 //=======================================================================
234
235 QList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
236 {
237   QList<QVariant> types;
238   SMESH_Actor* actor = getActor( ind );
239   if ( actor ) {
240     unsigned int aMode = actor->GetEntityMode();
241     if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume");
242     if ( aMode & SMESH_Actor::eFaces  ) types.append( "Face"  );
243     if ( aMode & SMESH_Actor::eEdges  ) types.append( "Edge"  );
244   }
245   return types;
246 }
247
248 //=======================================================================
249 //function : controlMode
250 //purpose  : return SMESH_Actor::eControl
251 //=======================================================================
252
253 QString SMESHGUI_Selection::controlMode( int ind ) const
254 {
255   SMESH_Actor* actor = getActor( ind );
256   if ( actor ) {
257     switch( actor->GetControlMode() ) {
258     case SMESH_Actor::eLength:            return "eLength";
259     case SMESH_Actor::eLength2D:          return "eLength2D";
260     case SMESH_Actor::eFreeEdges:         return "eFreeEdges";
261     case SMESH_Actor::eFreeNodes:         return "eFreeNodes";
262     case SMESH_Actor::eFreeBorders:       return "eFreeBorders";
263     case SMESH_Actor::eFreeFaces:         return "eFreeFaces";
264     case SMESH_Actor::eMultiConnection:   return "eMultiConnection";
265     case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
266     case SMESH_Actor::eArea:              return "eArea";
267     case SMESH_Actor::eVolume3D:          return "eVolume3D";
268     case SMESH_Actor::eTaper:             return "eTaper";
269     case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
270     case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
271     case SMESH_Actor::eMinimumAngle:      return "eMinimumAngle";
272     case SMESH_Actor::eWarping:           return "eWarping";
273     case SMESH_Actor::eSkew:              return "eSkew";
274     default:;
275     }
276   }
277   return "eNone";
278 }
279
280 //=======================================================================
281 //function : facesOrientationMode
282 //purpose  : 
283 //=======================================================================
284
285 QString SMESHGUI_Selection::facesOrientationMode( int ind ) const
286 {
287   SMESH_Actor* actor = getActor( ind );
288   if ( actor ) {
289     if ( actor->GetFacesOriented() )
290       return "IsOriented";
291     return "IsNotOriented";
292   }
293   return "Unknown";
294 }
295
296 //=======================================================================
297 //function : isAutoColor
298 //purpose  : 
299 //=======================================================================
300
301 bool SMESHGUI_Selection::isAutoColor( int ind ) const
302 {
303   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
304   {
305     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
306     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
307
308     if ( ! CORBA::is_nil( obj )) {
309       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
310       if ( ! mesh->_is_nil() )
311         return mesh->GetAutoColor();
312     }
313   }
314   return false;
315 }
316
317 //=======================================================================
318 //function : numberOfNodes
319 //purpose  : 
320 //=======================================================================
321
322 int SMESHGUI_Selection::numberOfNodes( int ind ) const
323 {
324   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
325   {
326     _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
327     CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
328
329     if ( ! CORBA::is_nil( obj )) {
330       SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
331       if ( ! mesh->_is_nil() )
332         return mesh->NbNodes();
333       SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
334       if ( !aSubMeshObj->_is_nil() )
335         return aSubMeshObj->GetNumberOfNodes(true);
336       SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
337       if ( !aGroupObj->_is_nil() )
338         return aGroupObj->Size();
339     }
340   }
341   return 0;
342 }
343
344 //=======================================================================
345 //function : isComputable
346 //purpose  : 
347 //=======================================================================
348
349 QVariant SMESHGUI_Selection::isComputable( int ind ) const
350 {
351   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
352   {
353 /*    Handle(SALOME_InteractiveObject) io =
354       static_cast<LightApp_DataOwner*>( myDataOwners[ ind ].get() )->IO();
355     if ( !io.IsNull() ) {
356       SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io); // m,sm,gr->m
357       if ( !mesh->_is_nil() ) {*/
358         _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
359         //FindSObject( mesh );
360         if ( so ) {
361           CORBA::Object_var obj = SMESH::SObjectToObject(so, SMESH::GetActiveStudyDocument());
362           if(!CORBA::is_nil(obj)){
363             SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
364             if (!mesh->_is_nil()){
365               if(mesh->HasShapeToMesh()) {
366                 GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
367                 return QVariant( !shape->_is_nil() );
368               }
369               else
370               {
371                 return QVariant(!mesh->NbFaces()==0);
372               }
373             }
374             else
375             {
376               GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
377               return QVariant( !shape->_is_nil() );
378             }
379           }
380         }
381 //      }
382 //    }
383   }
384   return QVariant( false );
385 }
386
387 //=======================================================================
388 //function : hasReference
389 //purpose  : 
390 //=======================================================================
391
392 QVariant SMESHGUI_Selection::hasReference( int ind ) const
393 {
394   return QVariant( isReference( ind ) );
395 }
396
397 //=======================================================================
398 //function : isVisible
399 //purpose  : 
400 //=======================================================================
401
402 QVariant SMESHGUI_Selection::isVisible( int ind ) const
403 {
404   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
405   {
406     QString ent = entry( ind );
407     SMESH_Actor* actor = SMESH::FindActorByEntry( ent.toLatin1().data() );
408     if ( actor && actor->hasIO() ) {
409       if(SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView())
410         return QVariant( aViewWindow->isVisible( actor->getIO() ) );
411     }
412   }
413   return QVariant( false );
414 }
415
416 //=======================================================================
417 //function : type
418 //purpose  : 
419 //=======================================================================
420
421 int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
422 {
423   _PTR(SObject) obj (study->FindObjectID(entry.toLatin1().data()));
424   if( !obj )
425     return -1;
426
427   _PTR(SObject) ref;
428   if( obj->ReferencedObject( ref ) )
429     obj = ref;
430
431   _PTR(SObject) objFather = obj->GetFather();
432   _PTR(SComponent) objComponent = obj->GetFatherComponent();
433
434   if( objComponent->ComponentDataType()!="SMESH" )
435     return -1;
436
437   if( objComponent->GetIOR()==obj->GetIOR() )
438     return COMPONENT;
439
440   int aLevel = obj->Depth() - objComponent->Depth(),
441       aFTag = objFather->Tag(),
442       anOTag = obj->Tag(),
443       res = -1;
444
445   switch (aLevel)
446   {
447   case 1:
448     if (anOTag >= SMESH::Tag_FirstMeshRoot)
449       res = MESH;
450     break;
451   case 2:
452     switch (aFTag)
453     {
454     case SMESH::Tag_HypothesisRoot:
455       res = HYPOTHESIS;
456       break;
457     case SMESH::Tag_AlgorithmsRoot:
458       res = ALGORITHM;
459       break;
460     }
461     break;
462   case 3:
463     switch (aFTag)
464     {
465     case SMESH::Tag_SubMeshOnVertex:
466       res = SUBMESH_VERTEX;
467       break;
468     case SMESH::Tag_SubMeshOnEdge:
469       res = SUBMESH_EDGE;
470       break;
471     case SMESH::Tag_SubMeshOnFace:
472       res = SUBMESH_FACE;
473       break;
474     case SMESH::Tag_SubMeshOnSolid:
475       res = SUBMESH_SOLID;
476       break;
477     case SMESH::Tag_SubMeshOnCompound:
478       res = SUBMESH_COMPOUND;
479       break;
480     default:
481       if (aFTag >= SMESH::Tag_FirstGroup)
482         res = GROUP;
483       else
484         res = SUBMESH;
485     }
486     break;
487   }
488
489   return res;
490 }
491
492 //=======================================================================
493 //function : typeName
494 //purpose  : 
495 //=======================================================================
496
497 QString SMESHGUI_Selection::typeName( const int t )
498 {
499   switch( t )
500   {
501   case HYPOTHESIS:
502     return "Hypothesis";
503   case ALGORITHM:
504     return "Algorithm";
505   case MESH:
506     return "Mesh";
507   case SUBMESH:
508     return "SubMesh";
509   case MESHorSUBMESH:
510     return "Mesh or submesh";
511   case SUBMESH_VERTEX:
512     return "Mesh vertex";
513   case SUBMESH_EDGE:
514     return "Mesh edge";
515   case SUBMESH_FACE:
516     return "Mesh face";
517   case SUBMESH_SOLID:
518     return "Mesh solid";
519   case SUBMESH_COMPOUND:
520     return "Mesh compound";
521   case GROUP:
522     return "Group";
523   case COMPONENT:
524     return "Component";
525   default:
526     return "Unknown";
527   }
528 }
529
530 bool SMESHGUI_Selection::isImported( const int ind ) const
531 {
532   QString e = entry( ind );
533   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
534   bool res = false;
535   if( SO )
536   {
537     SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( SO ) );
538     if( !aMesh->_is_nil() )
539     {
540       SALOME_MED::MedFileInfo* inf = aMesh->GetMEDFileInfo();
541       res = strlen( (char*)inf->fileName ) > 0;
542     }
543   }
544   return res;
545 }
546
547 //=======================================================================
548 //function : groupType
549 //purpose  : 
550 //=======================================================================
551
552 QString SMESHGUI_Selection::groupType( int ind ) const
553 {
554   QString e = entry( ind );
555   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
556   QString type;
557   if( SO )
558   {
559     CORBA::Object_var obj = SMESH::SObjectToObject( SO );
560   
561     SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( obj );
562     SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( obj );
563     if( !aGroup->_is_nil() )
564       type = QString( "Group" );
565     else if ( !aGroupOnGeom->_is_nil() )
566       type = QString( "GroupOnGeom" );
567   }
568   return type;
569 }
570