1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SMESHGUI_SelectionProxy.h"
26 #include "SMESHGUI_Utils.h"
27 #include "SMESHGUI_VTKUtils.h"
28 #include "SMESH_Actor.h"
30 #include <SALOMEconfig.h>
31 #include CORBA_SERVER_HEADER(SMESH_Group)
33 #include <SALOMEDSClient_Study.hxx>
34 #include <SUIT_ResourceMgr.h>
36 ////////////////////////////////////////////////////////////////////////////////
37 /// \class SMESHGUI_SelectionProxy
38 /// \brief Provide operations over the selected object.
40 /// The selection proxy class is aimed to use in dialogs to access mesh object
41 /// data either from actor or directly from CORBA reference, depending on what
42 /// of them is accessible.
43 /// This is useful in situations when some information is needed, but an actor
44 /// was not created yet.
46 /// Selection proxy can be constructed in two ways:
47 /// - From interactive object: this performs full proxy initialization including
48 /// pick-up of an actor from the current viewer if it exists.
49 /// - From mesh source object (CORBA reference); for performance reasons in this
50 /// case full initialization is not immediately done and performed only when
52 ////////////////////////////////////////////////////////////////////////////////
55 \brief Default constructor. Creates null proxy.
57 SMESHGUI_SelectionProxy::SMESHGUI_SelectionProxy(): myActor(0), myDirty(false)
63 \param io Interactive object.
65 SMESHGUI_SelectionProxy::SMESHGUI_SelectionProxy( const Handle(SALOME_InteractiveObject)& io ): myActor(0), myDirty(true)
67 myObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( io );
73 \param object Mesh source.
75 SMESHGUI_SelectionProxy::SMESHGUI_SelectionProxy( SMESH::SMESH_IDSource_ptr object ): myActor(0), myDirty(true)
77 if ( !CORBA::is_nil( object ) )
78 myObject = SMESH::SMESH_IDSource::_duplicate( object );
82 \brief Copy constructor.
83 \param other Proxy being copied.
85 SMESHGUI_SelectionProxy::SMESHGUI_SelectionProxy( const SMESHGUI_SelectionProxy& other )
88 myObject = other.myObject;
89 myActor = other.myActor;
90 myDirty = other.myDirty;
94 \brief Perform internal initialization.
97 void SMESHGUI_SelectionProxy::init()
100 myIO = new SALOME_InteractiveObject(); // create dummy IO to avoid crashes when accesing it
102 if ( !CORBA::is_nil( myObject ) )
104 if ( !myIO->hasEntry() )
106 _PTR(SObject) sobj = SMESH::ObjectToSObject( myObject.in() );
108 myIO = new SALOME_InteractiveObject( sobj->GetID().c_str(), "SMESH", sobj->GetName().c_str() );
110 if ( !myActor && myIO->hasEntry() )
111 myActor = SMESH::FindActorByEntry( myIO->getEntry() );
117 \brief Assignment operator.
118 \param other Proxy being copied.
120 SMESHGUI_SelectionProxy& SMESHGUI_SelectionProxy::operator= ( const SMESHGUI_SelectionProxy& other )
123 myObject = other.myObject;
124 myActor = other.myActor;
125 myDirty = other.myDirty;
130 \brief Equality comparison operator.
131 \param other Proxy to compare with.
132 \return \c true if two proxies are equal; \c false otherwise.
134 bool SMESHGUI_SelectionProxy::operator== ( const SMESHGUI_SelectionProxy& other )
136 return !CORBA::is_nil( myObject ) && !CORBA::is_nil( other.myObject ) &&
137 myObject->_is_equivalent( other.myObject );
141 \brief Try to re-initialize proxy.
143 void SMESHGUI_SelectionProxy::refresh()
149 \brief Check if proxy is null.
150 \return \c true if proxy is null; \c false otherwise.
152 bool SMESHGUI_SelectionProxy::isNull() const
154 return CORBA::is_nil( myObject );
158 \brief Boolean conversion operator.
159 \return \c true if proxy is not null; \c false otherwise.
161 SMESHGUI_SelectionProxy::operator bool() const
167 \brief Get interactive object.
168 \return Interactive object referenced by proxy.
170 const Handle(SALOME_InteractiveObject)& SMESHGUI_SelectionProxy::io() const
173 const_cast<SMESHGUI_SelectionProxy*>(this)->init();
178 \brief Get mesh object.
179 \return Mesh object (mesh, sub-mesh, group, etc.) referenced by proxy.
181 SMESH::SMESH_IDSource_ptr SMESHGUI_SelectionProxy::object() const
183 return SMESH::SMESH_IDSource::_duplicate( myObject );
188 \return Actor referenced by proxy.
190 SMESH_Actor* SMESHGUI_SelectionProxy::actor() const
193 const_cast<SMESHGUI_SelectionProxy*>(this)->init();
198 \brief Get object's validity.
200 Mesh object is valid if it is null and information stored in it is valid.
202 \return \c true if object is valid; \c false otherwise.
204 bool SMESHGUI_SelectionProxy::isValid() const
206 return !isNull() && myObject->IsMeshInfoCorrect();
210 \brief Load mesh object from study file.
212 void SMESHGUI_SelectionProxy::load()
216 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
217 if ( !CORBA::is_nil( mesh ) )
224 \return Mesh object's name.
226 QString SMESHGUI_SelectionProxy::name() const
230 value = io()->getName();
236 \return Mesh object's type.
238 SMESHGUI_SelectionProxy::Type SMESHGUI_SelectionProxy::type() const
240 Type value = Unknown;
243 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject );
244 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( myObject );
245 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject );
246 SMESH::SMESH_Group_var sGroup = SMESH::SMESH_Group::_narrow( myObject );
247 SMESH::SMESH_GroupOnGeom_var gGroup = SMESH::SMESH_GroupOnGeom::_narrow( myObject );
248 SMESH::SMESH_GroupOnFilter_var fGroup = SMESH::SMESH_GroupOnFilter::_narrow( myObject );
250 if ( !CORBA::is_nil( mesh ) )
252 else if ( !CORBA::is_nil( submesh ) )
254 else if ( !CORBA::is_nil( sGroup ) )
256 else if ( !CORBA::is_nil( gGroup ) )
258 else if ( !CORBA::is_nil( fGroup ) )
260 else if ( !CORBA::is_nil( group ) )
267 \brief Get mesh information.
268 \return Statistics on stored mesh object.
270 SMESHGUI_MeshInfo SMESHGUI_SelectionProxy::meshInfo() const
272 SMESHGUI_MeshInfo info;
275 SMESH::long_array_var data = myObject->GetMeshInfo();
276 for ( uint type = SMESH::Entity_Node; type < SMESH::Entity_Last; type++ )
278 if ( type < data->length() )
279 info.addInfo( type, data[ type ] );
286 \brief Get parent mesh.
287 \return Proxy object that stores parent mesh object.
288 \note For proxy that stores a mesh, returns its copy.
290 SMESHGUI_SelectionProxy SMESHGUI_SelectionProxy::mesh() const
292 SMESHGUI_SelectionProxy parent;
294 parent = SMESHGUI_SelectionProxy( (SMESH::SMESH_Mesh_var) myObject->GetMesh() ); // cast to var to avoid leaks
299 \brief Check if parent mesh has shape to mesh.
300 \return \c true if Parent mesh is built on a shape; \c false otherwise.
301 \note For group or submesh, this method checks that parent mesh has a shape.
303 bool SMESHGUI_SelectionProxy::hasShapeToMesh() const
308 SMESHGUI_SelectionProxy parent = mesh();
311 SMESH::SMESH_Mesh_var m = SMESH::SMESH_Mesh::_narrow( (SMESH::SMESH_IDSource_var)parent.object() ); // cast to var to avoid leaks
312 result = m->HasShapeToMesh();
319 \brief Get referenced GEOM object.
320 \return GEOM object referenced by selection proxy.
322 The result contains valid pointer only if proxy refers to mesh, sub-mesh
323 or group created on a geometry.
325 GEOM::GEOM_Object_ptr SMESHGUI_SelectionProxy::shape() const
327 GEOM::GEOM_Object_var shape;
330 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject );
331 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( myObject );
332 SMESH::SMESH_GroupOnGeom_var group = SMESH::SMESH_GroupOnGeom::_narrow( myObject );
333 if ( !CORBA::is_nil( mesh ) )
334 shape = mesh->GetShapeToMesh();
335 else if ( !CORBA::is_nil( submesh ) )
336 shape = submesh->GetSubShape();
337 else if ( !CORBA::is_nil( group ) )
338 shape = group->GetShape();
340 return shape._retn();
344 \brief Get name of referenced GEOM object.
345 \return Name of GEOM object referenced by selection proxy.
347 The result contains non-empty name only if proxy refers to mesh, sub-mesh
348 or group created on a geometry, and if that geometry has valid name.
350 QString SMESHGUI_SelectionProxy::shapeName() const
355 GEOM::GEOM_Object_var gobj = shape();
356 _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
358 name = QString::fromStdString( sobj->GetName() );
364 \brief Get type of referenced GEOM object.
365 \return Type of GEOM object referenced by selection proxy.
367 The result contains valid type only if proxy refers to mesh, sub-mesh
368 or group created on a geometry.
370 int SMESHGUI_SelectionProxy::shapeType() const
375 GEOM::GEOM_Object_var gobj = shape();
376 if ( !CORBA::is_nil( gobj ) )
377 type = gobj->GetShapeType();
383 \brief Check if mesh has been loaded from study file.
384 \return \c true if mesh was loaded; \c false otherwise.
386 bool SMESHGUI_SelectionProxy::isMeshLoaded() const
388 bool result = true; // set default to true to avoid side effects
391 SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
392 if ( !CORBA::is_nil( mesh ) )
393 result = mesh->IsLoaded();
399 \brief Get MED file information.
400 \return MED file information.
402 The result contains valid data only if proxy refers to mesh object
403 which has been imported from the MED file.
405 SMESHGUI_MedFileInfo SMESHGUI_SelectionProxy::medFileInfo() const
407 SMESHGUI_MedFileInfo info;
410 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject );
411 if ( !CORBA::is_nil( mesh ) )
413 SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo();
414 info.setFileName( inf->fileName.in() );
415 info.setSize( inf->fileSize );
416 info.setVersion( inf->major, inf->minor, inf->release );
423 \brief Get child sub-meshes.
424 \return List of sub-meshes for mesh object; empty list for other types.
426 QList<SMESHGUI_SelectionProxy> SMESHGUI_SelectionProxy::submeshes() const
428 QList<SMESHGUI_SelectionProxy> lst;
431 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject );
432 if ( !CORBA::is_nil( mesh ) )
434 SMESH::submesh_array_var array = mesh->GetSubMeshes();
435 for ( uint i = 0 ; i < array->length(); i++ )
436 lst << SMESHGUI_SelectionProxy( array[i].in() );
443 \brief Get child groups.
444 \return List of groups for mesh object; empty list for other types.
446 QList<SMESHGUI_SelectionProxy> SMESHGUI_SelectionProxy::groups() const
448 QList<SMESHGUI_SelectionProxy> lst;
451 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( myObject );
452 if ( !CORBA::is_nil( mesh ) )
454 SMESH::ListOfGroups_var array = mesh->GetGroups();
455 for ( uint i = 0 ; i < array->length(); i++ )
456 lst << SMESHGUI_SelectionProxy( array[i].in() );
463 \brief Get element type (for group). For other mesh objects result is undefined.
464 \return Group's element type.
466 SMESH::ElementType SMESHGUI_SelectionProxy::elementType() const
468 SMESH::ElementType value = SMESH::ALL;
471 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject );
472 if ( !CORBA::is_nil( group ) )
473 value = group->GetType();
479 \brief Get color (for group). For other mesh objects result is undefined.
480 \return Group's color.
482 QColor SMESHGUI_SelectionProxy::color() const
487 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject );
488 if ( !CORBA::is_nil( group ) )
490 SALOMEDS::Color c = group->GetColor();
491 result = QColor::fromRgbF( c.R, c.G, c.B );
498 \brief Get size (for group). For other mesh objects result is undefined.
499 \param autoCompute Compute size if it is unavailable. Defaults to \c false.
500 \return Group's size.
502 int SMESHGUI_SelectionProxy::size( bool autoCompute ) const
504 // note: size is not computed for group on filter for performance reasons, see IPAL52831
508 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject );
509 if ( !CORBA::is_nil( group ) )
511 if ( type() == GroupFilter )
512 // for group on filter we check if value is already computed and cached
513 autoCompute |= group->IsNodeInfoAvailable();
515 // for other groups we force autoCompute to true
518 result = group->Size();
525 \brief Get number of underlying nodes (for group of elements). For other
526 mesh objects result is undefined.
527 \param autoCompute Compute size if it is unavailable. Defaults to \c false.
528 \return Number of nodes contained in group.
530 int SMESHGUI_SelectionProxy::nbNodes( bool autoCompute ) const
532 // note: nb of nodes is not computed automatically for performance reasons
536 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject );
537 if ( !CORBA::is_nil( group ) && ( autoCompute || isMeshLoaded() ) )
539 int groupSize = size( autoCompute );
540 if ( groupSize >= 0 )
542 int limit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
543 if ( group->IsNodeInfoAvailable() || limit <= 0 || groupSize <= limit )
544 result = group->GetNumberOfNodes();
552 \brief Get list of nodes / elements IDs for the mesh group.
553 \return List of IDs for group object; empty list for other types.
555 QSet<uint> SMESHGUI_SelectionProxy::ids() const
560 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( myObject );
561 if ( !CORBA::is_nil( group ) )
563 SMESH::long_array_var seq = group->GetListOfID();
564 for ( int i = 0, n = seq->length(); i < n; i++ )
565 result << (uint)seq[i];
571 ////////////////////////////////////////////////////////////////////////////////
572 /// \class SMESHGUI_MeshInfo
573 /// \brief Store statistics on mesh object.
574 ////////////////////////////////////////////////////////////////////////////////
579 SMESHGUI_MeshInfo::SMESHGUI_MeshInfo()
584 \brief Add information on given entity type.
585 \param type Entity type.
586 \param value Number of entities.
588 void SMESHGUI_MeshInfo::addInfo( int type, long value )
590 myInfo[type] = value;
594 \brief Get number of entities of given type.
595 \param type Entity type.
596 \return Number of entities.
598 uint SMESHGUI_MeshInfo::info( int type ) const
600 return myInfo.value( type, 0U );
604 \brief Access operator.
605 \param type Entity type.
606 \return Number of entities.
608 uint SMESHGUI_MeshInfo::operator[] ( int type )
610 return (uint)info( type );
614 \brief Get total number of entities for types in given range.
615 \param fromType Lower entity type.
616 \param toType Upper entity type.
617 \return Number of entities.
619 uint SMESHGUI_MeshInfo::count( int fromType, int toType ) const
622 for ( int type = fromType; type <= toType; type++ )
623 value += info( type );
627 ////////////////////////////////////////////////////////////////////////////////
628 /// \class SMESHGUI_MedFileInfo
629 /// \brief Provide operations over the selected object
630 ////////////////////////////////////////////////////////////////////////////////
635 SMESHGUI_MedFileInfo::SMESHGUI_MedFileInfo()
640 \brief Get validity status.
642 MED file information is valid if at least stored file name is not null.
644 \return \c true if MED file info is valid; \c false otherwise.
646 bool SMESHGUI_MedFileInfo::isValid() const
648 return !myFileName.isEmpty();
652 \brief Get file name for mesh imported from MED file.
653 \return MED file name.
655 QString SMESHGUI_MedFileInfo::fileName() const
661 \brief Set file name for mesh imported from MED file.
662 \param fileName MED file name.
664 void SMESHGUI_MedFileInfo::setFileName( const QString& fileName )
666 myFileName = fileName;
670 \brief Get file size for mesh imported from MED file.
671 \return MED file size.
673 uint SMESHGUI_MedFileInfo::size() const
679 \brief Set file size for mesh imported from MED file.
680 \param size MED file size.
682 void SMESHGUI_MedFileInfo::setSize( uint size )
688 \brief Get version of format for mesh imported from MED file.
689 \return MED file format version.
691 QString SMESHGUI_MedFileInfo::version() const
693 QString v = QString( "%1" ).arg( myMajor );
694 if ( myMinor > 0 || myRelease > 0 ) v += QString( ".%1" ).arg( myMinor );
695 else if ( myMajor > 0 ) v += ".0";
696 if ( myRelease > 0 ) v += QString( ".%1" ).arg( myRelease );
701 \brief Set version of format for mesh imported from MED file.
702 \param major Major version number.
703 \param minor Minor version number.
704 \param release Release version number.
706 void SMESHGUI_MedFileInfo::setVersion( uint major, uint minor, uint release )