X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Mesh_i.cxx;h=b8635aadf7c8528efb4ec347806d9cab1336fc75;hp=a21535af803ff4dca0c5b7f497956d8926985719;hb=89f13ac88ccbc3d7b2a7c0f58891f20056404489;hpb=9357f5c87098aff2b95b754d69f66c76d2df9c24 diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index a21535af8..b8635aadf 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,60 +1,59 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Mesh_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// -#include "SMESH_Mesh_i.hxx" -#include "SMESH_Filter_i.hxx" -#include "SMESH_Gen_i.hxx" -#include "SMESH_Group_i.hxx" -#include "SMESH_MEDMesh_i.hxx" -#include "SMESH_MeshEditor_i.hxx" -#include "SMESH_PythonDump.hxx" -#include "SMESH_subMesh_i.hxx" +#include "SMESH_Mesh_i.hxx" #include "DriverMED_R_SMESHDS_Mesh.h" #include "DriverMED_W_SMESHDS_Mesh.h" -#include "SMDS_VolumeTool.hxx" +#include "SMDS_EdgePosition.hxx" #include "SMDS_ElemIterator.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMDS_IteratorOnIterators.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_VolumeTool.hxx" #include "SMESHDS_Command.hxx" #include "SMESHDS_CommandType.hxx" #include "SMESHDS_GroupOnGeom.hxx" +#include "SMESH_Filter_i.hxx" +#include "SMESH_Gen_i.hxx" #include "SMESH_Group.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_MEDMesh_i.hxx" #include "SMESH_MeshEditor.hxx" +#include "SMESH_MeshEditor_i.hxx" #include "SMESH_MesherHelper.hxx" -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" +#include "SMESH_PythonDump.hxx" +#include "SMESH_subMesh_i.hxx" -#include "OpUtil.hxx" -#include "SALOME_NamingService.hxx" -#include "Utils_CorbaException.hxx" -#include "Utils_ExceptHandlers.hxx" -#include "Utils_SINGLETON.hxx" -#include "utilities.h" -#include "GEOMImpl_Types.hxx" +#include +#include +#include +#include +#include +#include +#include // OCCT Includes #include @@ -90,7 +89,9 @@ using SMESH::TPythonDump; int SMESH_Mesh_i::myIdGenerator = 0; - +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ //============================================================================= /*! @@ -118,18 +119,49 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i::~SMESH_Mesh_i() { - INFOS("~SMESH_Mesh_i"); - map::iterator it; - for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) { - SMESH_GroupBase_i* aGroup = dynamic_cast( SMESH_Gen_i::GetServant( it->second ).in() ); - if ( aGroup ) { - // this method is colled from destructor of group (PAL6331) + MESSAGE("~SMESH_Mesh_i"); + +#ifdef WITHGENERICOBJ + // destroy groups + map::iterator itGr; + for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) { + if ( CORBA::is_nil( itGr->second )) + continue; + SMESH_GroupBase_i* aGroup = dynamic_cast(SMESH_Gen_i::GetServant(itGr->second).in()); + if (aGroup) { + // this method is called from destructor of group (PAL6331) //_impl->RemoveGroup( aGroup->GetLocalID() ); - - aGroup->Destroy(); + aGroup->myMeshServant = 0; + aGroup->UnRegister(); } } _mapGroups.clear(); + + // destroy submeshes + map::iterator itSM; + for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) { + if ( CORBA::is_nil( itSM->second )) + continue; + SMESH_subMesh_i* aSubMesh = dynamic_cast(SMESH_Gen_i::GetServant(itSM->second).in()); + if (aSubMesh) { + aSubMesh->UnRegister(); + } + } + _mapSubMeshIor.clear(); + + // destroy hypotheses + map::iterator itH; + for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) { + if ( CORBA::is_nil( itH->second )) + continue; + SMESH_Hypothesis_i* aHypo = dynamic_cast(SMESH_Gen_i::GetServant(itH->second).in()); + if (aHypo) { + aHypo->UnRegister(); + } + } + _mapHypo.clear(); +#endif + delete _impl; } @@ -308,6 +340,34 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) return ConvertDriverMEDReadStatus(status); } +//================================================================================ +/*! + * \brief Imports mesh data from the CGNS file + */ +//================================================================================ + +SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName, + const int theMeshIndex, + std::string& theMeshName ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + int status; + try { + status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName ); + } + catch( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + catch ( ... ) { + THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM); + } + + CreateGroupServants(); + + return ConvertDriverMEDReadStatus(status); +} + //================================================================================ /*! * \brief Return string representation of a MED file version comprising nbDigits @@ -474,6 +534,9 @@ SMESH_Hypothesis::Hypothesis_Status status = _impl->AddHypothesis(myLocSubShape, hypId); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) { _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp ); +#ifdef WITHGENERICOBJ + _mapHypo[hypId]->Register(); +#endif // assure there is a corresponding submesh if ( !_impl->IsMainShape( myLocSubShape )) { int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); @@ -602,6 +665,42 @@ throw(SALOME::SALOME_Exception) return aList._retn(); } +SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if (MYDEBUG) MESSAGE("GetSubMeshes"); + + SMESH::submesh_array_var aList = new SMESH::submesh_array(); + + // Python Dump + TPythonDump aPythonDump; + if ( !_mapSubMeshIor.empty() ) + aPythonDump << "[ "; + + try { + aList->length( _mapSubMeshIor.size() ); + int i = 0; + map::iterator it = _mapSubMeshIor.begin(); + for ( ; it != _mapSubMeshIor.end(); it++ ) { + if ( CORBA::is_nil( it->second )) continue; + aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second ); + // Python Dump + if (i > 1) aPythonDump << ", "; + aPythonDump << it->second; + } + aList->length( i ); + } + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + // Update Python script + if ( !_mapSubMeshIor.empty() ) + aPythonDump << " ] = " << _this() << ".GetSubMeshes()"; + + return aList._retn(); +} + //============================================================================= /*! * @@ -625,6 +724,13 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap //Get or Create the SMESH_subMesh object implementation int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); + + if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape )) + { + TopoDS_Iterator it( myLocSubShape ); + if ( it.More() ) + THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM); + } subMesh = getSubMesh( subMeshId ); // create a new subMesh object servant if there is none for the shape @@ -684,25 +790,6 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) removeSubMesh( theSubMesh, aSubShapeObject.in() ); } -//============================================================================= -/*! - * ElementTypeString - */ -//============================================================================= -#define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum; -inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType) -{ - switch (theElemType) { - CASE2STRING( ALL ); - CASE2STRING( NODE ); - CASE2STRING( EDGE ); - CASE2STRING( FACE ); - CASE2STRING( VOLUME ); - default:; - } - return ""; -} - //============================================================================= /*! * @@ -724,7 +811,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType if ( !aSO->_is_nil()) { // Update Python script TPythonDump() << aSO << " = " << _this() << ".CreateGroup( " - << ElementTypeString(theElemType) << ", '" << theName << "' )"; + << theElemType << ", '" << theName << "' )"; } } return aNewGroup._retn(); @@ -736,9 +823,10 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType * */ //============================================================================= -SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, - const char* theName, - GEOM::GEOM_Object_ptr theGeomObj) +SMESH::SMESH_GroupOnGeom_ptr +SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, + const char* theName, + GEOM::GEOM_Object_ptr theGeomObj) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -757,8 +845,7 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementTy if ( !aSO->_is_nil()) { // Update Python script TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM(" - << ElementTypeString(theElemType) << ", '" << theName << "', " - << theGeomObj << " )"; + << theElemType << ", '" << theName << "', " << theGeomObj << " )"; } } } @@ -766,6 +853,53 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementTy return aNewGroup._retn(); } +//================================================================================ +/*! + * \brief Creates a group whose contents is defined by filter + * \param theElemType - group type + * \param theName - group name + * \param theFilter - the filter + * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter + */ +//================================================================================ + +SMESH::SMESH_GroupOnFilter_ptr +SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, + const char* theName, + SMESH::Filter_ptr theFilter ) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + + if ( CORBA::is_nil( theFilter )) + THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM); + + SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter ); + if ( !predicate ) + THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM); + + SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow + ( createGroup( theElemType, theName, TopoDS_Shape(), predicate )); + + TPythonDump pd; + if ( !aNewGroup->_is_nil() ) + aNewGroup->SetFilter( theFilter ); + + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SALOMEDS::SObject_var aSO = + _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup, + GEOM::GEOM_Object::_nil(), theName); + if ( !aSO->_is_nil()) { + // Update Python script + pd << aSO << " = " << _this() << ".CreateGroupFromFilter(" + << theElemType << ", '" << theName << "', " << theFilter << " )"; + } + } + + return aNewGroup._retn(); +} + //============================================================================= /*! * @@ -819,8 +953,7 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup SMESH::long_array_var anIds = aGroup->GetListOfID(); SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); - // Update Python script - TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; + TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup() // Remove contents if ( aGroup->GetType() == SMESH::NODE ) @@ -831,12 +964,10 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup // Remove group RemoveGroup( theGroup ); - // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup() - _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId()); - _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId()); + // Update Python script + pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; } - //================================================================================ /*! * \brief Get the list of groups existing in the mesh @@ -879,6 +1010,7 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception) return aList._retn(); } + //============================================================================= /*! * Get number of groups existing in the mesh @@ -970,7 +1102,7 @@ throw (SALOME::SALOME_Exception) try { - NCollection_Map< int > anIds; + vector< int > anIds; SMESH::ElementType aType = SMESH::ALL; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { @@ -993,7 +1125,7 @@ throw (SALOME::SALOME_Exception) for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - anIds.Add( aCurrId ); + anIds.push_back( aCurrId ); } } @@ -1004,12 +1136,12 @@ throw (SALOME::SALOME_Exception) // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; anIter.More(); anIter.Next(), i++ ) + //NCollection_Map< int >::Iterator anIter( anIds ); + for ( int i = 0; iAdd( aResIds ); @@ -1135,14 +1267,14 @@ throw (SALOME::SALOME_Exception) // create map of ids int nbGrp = theGroups.length(); - NCollection_Map< int > anIds; + vector< int > anIds; NCollection_DataMap< int, int >::Iterator anIter( anIdToCount ); for ( ; anIter.More(); anIter.Next() ) { int aCurrId = anIter.Key(); int aCurrNb = anIter.Value(); if ( aCurrNb == nbGrp ) - anIds.Add( aCurrId ); + anIds.push_back( aCurrId ); } // Create group @@ -1152,12 +1284,12 @@ throw (SALOME::SALOME_Exception) // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator aListIter( anIds ); - for ( int i = 0; aListIter.More(); aListIter.Next(), i++ ) + //NCollection_Map< int >::Iterator aListIter( anIds ); + for ( int i = 0; iAdd( aResIds ); @@ -1254,7 +1386,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( try { - NCollection_Map< int > aToolIds; + set< int > aToolIds; SMESH::ElementType aType = SMESH::ALL; int g, n; // iterate through tool groups @@ -1279,11 +1411,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - aToolIds.Add( aCurrId ); + aToolIds.insert( aCurrId ); } } - NCollection_Map< int > anIds; // result + vector< int > anIds; // result // Iterate through main group for ( g = 0, n = theMainGroups.length(); g < n; g++ ) @@ -1307,8 +1439,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - if ( !aToolIds.Contains( aCurrId ) ) - anIds.Add( aCurrId ); + if ( !aToolIds.count( aCurrId ) ) + anIds.push_back( aCurrId ); } } @@ -1319,12 +1451,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; anIter.More(); anIter.Next(), i++ ) + for (int i=0; iAdd( aResIds ); @@ -1376,7 +1507,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( { // Create map of nodes from all groups - NCollection_Map< int > aNodeMap; + set< int > aNodeMap; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { @@ -1395,7 +1526,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( int aCurrId = aCurrIds[ i ]; const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId ); if ( aNode ) - aNodeMap.Add( aNode->GetID() ); + aNodeMap.insert( aNode->GetID() ); } } else @@ -1413,7 +1544,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( const SMDS_MeshNode* aNode = dynamic_cast( aNodeIter->next() ); if ( aNode ) - aNodeMap.Add( aNode->GetID() ); + aNodeMap.insert( aNode->GetID() ); } } } @@ -1421,22 +1552,25 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( // Get result identifiers - NCollection_Map< int > aResultIds; + vector< int > aResultIds; if ( theElemType == SMESH::NODE ) { - NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - for ( ; aNodeIter.More(); aNodeIter.Next() ) - aResultIds.Add( aNodeIter.Value() ); + //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); + set::iterator iter = aNodeMap.begin(); + for ( ; iter != aNodeMap.end(); iter++ ) + aResultIds.push_back( *iter); } else { // Create list of elements of given dimension constructed on the nodes - NCollection_Map< int > anElemList; - NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - for ( ; aNodeIter.More(); aNodeIter.Next() ) + vector< int > anElemList; + //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); + //for ( ; aNodeIter.More(); aNodeIter.Next() ) + set::iterator iter = aNodeMap.begin(); + for ( ; iter != aNodeMap.end(); iter++ ) { const SMDS_MeshElement* aNode = - dynamic_cast( aMeshDS->FindNode( aNodeIter.Value() ) ); + dynamic_cast( aMeshDS->FindNode( *iter ) ); if ( !aNode ) continue; @@ -1446,15 +1580,16 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( const SMDS_MeshElement* anElem = dynamic_cast( anElemIter->next() ); if ( anElem && anElem->GetType() == anElemType ) - anElemList.Add( anElem->GetID() ); + anElemList.push_back( anElem->GetID() ); } } // check whether all nodes of elements are present in nodes map - NCollection_Map< int >::Iterator anIter( anElemList ); - for ( ; anIter.More(); anIter.Next() ) + //NCollection_Map< int >::Iterator anIter( anElemList ); + //for ( ; anIter.More(); anIter.Next() ) + for (int i=0; i< anElemList.size(); i++) { - const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() ); + const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] ); if ( !anElem ) continue; @@ -1464,14 +1599,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( { const SMDS_MeshNode* aNode = dynamic_cast( aNodeIter->next() ); - if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) ) + if ( !aNode || !aNodeMap.count( aNode->GetID() ) ) { isOk = false; break; } } if ( isOk ) - aResultIds.Add( anElem->GetID() ); + aResultIds.push_back( anElem->GetID() ); } } @@ -1483,11 +1618,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aResultIds.Extent() ); + aResIds->length( aResultIds.size() ); - NCollection_Map< int >::Iterator aResIter( aResultIds ); - for ( int i = 0; aResIter.More(); aResIter.Next(), i++ ) - aResIds[ i ] = aResIter.Value(); + //NCollection_Map< int >::Iterator aResIter( aResultIds ); + //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ ) + for (int i=0; i< aResultIds.size(); i++) + aResIds[ i ] = aResultIds[i]; aResGrp->Add( aResIds ); // Remove strings corresponding to group creation @@ -1860,11 +1996,11 @@ void SMESH_Mesh_i::CheckGeomGroupModif() //============================================================================= /*! - * \brief Create standalone group instead if group on geometry + * \brief Create standalone group from a group on geometry or filter */ //============================================================================= -SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup ) +SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup ) { SMESH::SMESH_Group_var aGroup; if ( theGroup->_is_nil() ) @@ -1877,6 +2013,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe if ( !aGroupToRem ) return aGroup._retn(); + const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )); + int anId = aGroupToRem->GetLocalID(); if ( !_impl->ConvertToStandalone( anId ) ) return aGroup._retn(); @@ -1895,15 +2033,29 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); if ( !aGroupSO->_is_nil() ) { - // remove reference to geometry - SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO); - for ( ; chItr->More(); chItr->Next() ) - // Remove group's child SObject - builder->RemoveObject( chItr->Value() ); + // remove reference to geometry + SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO); + for ( ; chItr->More(); chItr->Next() ) + // Remove group's child SObject + builder->RemoveObject( chItr->Value() ); // Update Python script TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( " << aGroupSO << " )"; + + // change icon of Group on Filter + if ( isOnFilter ) + { + SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes(); + const int isEmpty = ( elemTypes->length() == 0 ); + if ( !isEmpty ) + { + SALOMEDS::GenericAttribute_var anAttr = + builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" ); + SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr ); + pm->SetPixMap( "ICON_SMESH_TREE_GROUP" ); + } + } } } @@ -2025,16 +2177,32 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, */ //============================================================================= -SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType, - const char* theName, - const TopoDS_Shape& theShape ) +SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType, + const char* theName, + const TopoDS_Shape& theShape, + const SMESH_PredicatePtr& thePredicate ) { + std::string newName; + if ( !theName || strlen( theName ) == 0 ) + { + std::set< std::string > presentNames; + std::map::const_iterator i_gr = _mapGroups.begin(); + for ( ; i_gr != _mapGroups.end(); ++i_gr ) + presentNames.insert( i_gr->second->GetName() ); + do { + newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 ); + } while ( !presentNames.insert( newName ).second ); + theName = newName.c_str(); + } int anId; SMESH::SMESH_GroupBase_var aGroup; - if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) { + if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate )) + { SMESH_GroupBase_i* aGroupImpl; if ( !theShape.IsNull() ) aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId ); + else if ( thePredicate ) + aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId ); else aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); @@ -2071,13 +2239,17 @@ void SMESH_Mesh_i::removeGroup( const int theId ) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" ); if ( _mapGroups.find( theId ) != _mapGroups.end() ) { - removeGeomGroupData( _mapGroups[theId] ); + SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId]; _mapGroups.erase( theId ); - _impl->RemoveGroup( theId ); + removeGeomGroupData( group ); + if (! _impl->RemoveGroup( theId )) + { + // it seems to be a call up from _impl caused by hyp modification (issue 0020918) + RemoveGroup( group ); + } } } - //============================================================================= /*! * @@ -2174,6 +2346,19 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception) return _studyId; } +//============================================================================= +namespace +{ + //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from + // SMESH_Mesh::RemoveGroup() (issue 0020918) + struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp + { + SMESH_Mesh_i* _mesh; + TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {} + virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); } + }; +} + //============================================================================= /*! * @@ -2184,6 +2369,8 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl"); _impl = impl; + if ( _impl ) + _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this)); } //============================================================================= @@ -2242,6 +2429,36 @@ CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Ex return _impl->HasModificationsToDiscard(); } +static SALOMEDS::Color getUniqueColor( const std::list& theReservedColors ) +{ + const int MAX_ATTEMPTS = 100; + int cnt = 0; + double tolerance = 0.5; + SALOMEDS::Color col; + + bool ok = false; + while ( !ok ) { + // generate random color + double red = (double)rand() / RAND_MAX; + double green = (double)rand() / RAND_MAX; + double blue = (double)rand() / RAND_MAX; + // check existence in the list of the existing colors + bool matched = false; + std::list::const_iterator it; + for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) { + SALOMEDS::Color color = *it; + double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue ); + matched = tol < tolerance; + } + if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2; + ok = ( ++cnt == MAX_ATTEMPTS ) || !matched; + col.R = red; + col.G = green; + col.B = blue; + } + return col; +} + //============================================================================= /*! * @@ -2251,6 +2468,18 @@ void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOM { Unexpect aCatch(SALOME_SalomeException); _impl->SetAutoColor(theAutoColor); + + TPythonDump pyDump; // not to dump group->SetColor() from below code + pyDump<<_this()<<".SetAutoColor( "< aReservedColors; + map::iterator it = _mapGroups.begin(); + for ( ; it != _mapGroups.end(); it++ ) { + if ( CORBA::is_nil( it->second )) continue; + SALOMEDS::Color aColor = getUniqueColor( aReservedColors ); + it->second->SetColor( aColor ); + aReservedColors.push_back( aColor ); + } } //============================================================================= @@ -2319,25 +2548,21 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) } } -void SMESH_Mesh_i::ExportToMEDX (const char* file, - CORBA::Boolean auto_groups, - SMESH::MED_VERSION theVersion, - CORBA::Boolean overwrite) - throw(SALOME::SALOME_Exception) +string SMESH_Mesh_i::PrepareMeshNameAndGroups(const char* file, + CORBA::Boolean overwrite) { - Unexpect aCatch(SALOME_SalomeException); - // Perform Export PrepareForWriting(file, overwrite); - const char* aMeshName = "Mesh"; + string aMeshName = "Mesh"; SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() ); if ( !aMeshSO->_is_nil() ) { - aMeshName = aMeshSO->GetName(); + CORBA::String_var name = aMeshSO->GetName(); + aMeshName = name; // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes if ( !aStudy->GetProperties()->IsLocked() ) - { + { SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); SALOMEDS::AttributeExternalFileDef_var aFileName; @@ -2350,22 +2575,39 @@ void SMESH_Mesh_i::ExportToMEDX (const char* file, aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr); ASSERT(!aFileType->_is_nil()); aFileType->SetValue("FICHIERMED"); - } + } } } // Update Python script // set name of mesh before export - TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')"; - + TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')"; + // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportToMEDX( '" + return aMeshName; +} + +void SMESH_Mesh_i::ExportToMEDX (const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION theVersion, + CORBA::Boolean overwrite) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + string aMeshName = PrepareMeshNameAndGroups(file, true); + TPythonDump() << _this() << ".ExportToMEDX( r'" << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )"; - _impl->ExportMED( file, aMeshName, auto_groups, theVersion ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion ); } +//================================================================================ +/*! + * \brief Export a mesh to a med file + */ +//================================================================================ + void SMESH_Mesh_i::ExportToMED (const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion) @@ -2374,13 +2616,42 @@ void SMESH_Mesh_i::ExportToMED (const char* file, ExportToMEDX(file,auto_groups,theVersion,true); } +//================================================================================ +/*! + * \brief Export a mesh to a med file + */ +//================================================================================ + void SMESH_Mesh_i::ExportMED (const char* file, CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception) { - ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true); + ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true); } +//================================================================================ +/*! + * \brief Export a mesh to a SAUV file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportSAUV (const char* file, + CORBA::Boolean auto_groups) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + string aMeshName = PrepareMeshNameAndGroups(file, true); + TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )"; + _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups); +} + + +//================================================================================ +/*! + * \brief Export a mesh to a DAT file + */ +//================================================================================ + void SMESH_Mesh_i::ExportDAT (const char *file) throw(SALOME::SALOME_Exception) { @@ -2389,13 +2660,19 @@ void SMESH_Mesh_i::ExportDAT (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportDAT( '" << file << "' )"; + TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )"; // Perform Export PrepareForWriting(file); _impl->ExportDAT(file); } +//================================================================================ +/*! + * \brief Export a mesh to an UNV file + */ +//================================================================================ + void SMESH_Mesh_i::ExportUNV (const char *file) throw(SALOME::SALOME_Exception) { @@ -2404,13 +2681,19 @@ void SMESH_Mesh_i::ExportUNV (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportUNV( '" << file << "' )"; + TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )"; // Perform Export PrepareForWriting(file); _impl->ExportUNV(file); } +//================================================================================ +/*! + * \brief Export a mesh to an STL file + */ +//================================================================================ + void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) throw(SALOME::SALOME_Exception) { @@ -2419,13 +2702,162 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )"; + TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )"; // Perform Export PrepareForWriting(file); _impl->ExportSTL(file, isascii); } +//============================================================================= +/*! + * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource. + * It is used to export a part of mesh as a whole mesh. + */ +class SMESH_MeshPartDS : public SMESHDS_Mesh +{ +public: + SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart); + + virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; + virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const; + virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const; + virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const; + virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; + +private: + TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ]; + SMESHDS_Mesh* _meshDS; + /*! + * \brief Class used to access to protected data of SMDS_MeshInfo + */ + struct TMeshInfo : public SMDS_MeshInfo + { + void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); } + }; +}; + +//================================================================================ +/*! + * \brief Export a part of mesh to a med file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + ::SMESH::MED_VERSION version, + ::CORBA::Boolean overwrite) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + + PrepareForWriting(file, overwrite); + + string aMeshName = "Mesh"; + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart ); + if ( !SO->_is_nil() ) { + CORBA::String_var name = SO->GetName(); + aMeshName = name; + } + } + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS ); + + TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', " + << auto_groups << ", " << version << ", " << overwrite << " )"; +} + +//================================================================================ +/*! + * \brief Export a part of mesh to a DAT file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + + PrepareForWriting(file); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportDAT(file,&partDS); + + TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )"; +} +//================================================================================ +/*! + * \brief Export a part of mesh to an UNV file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + + PrepareForWriting(file); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportUNV(file, &partDS); + + TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )"; +} +//================================================================================ +/*! + * \brief Export a part of mesh to an STL file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + ::CORBA::Boolean isascii) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + + PrepareForWriting(file); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportSTL(file, isascii, &partDS); + + TPythonDump() << _this() << ".ExportPartToSTL( " + << meshPart<< ", r'" << file << "', " << isascii << ")"; +} + +//================================================================================ +/*! + * \brief Export a part of mesh to an STL file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean overwrite) + throw (SALOME::SALOME_Exception) +{ +#ifdef WITH_CGNS + Unexpect aCatch(SALOME_SalomeException); + + PrepareForWriting(file,overwrite); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportCGNS(file, &partDS); + + TPythonDump() << _this() << ".ExportCGNS( " + << meshPart<< ", r'" << file << "', " << overwrite << ")"; +#else + THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); +#endif +} + //============================================================================= /*! * @@ -2711,7 +3143,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy // No sense in returning ids of elements along with ids of nodes: // when theElemType == SMESH::ALL, return node ids only if // there are no elements - if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 ) + if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) ) return GetNodesId(); aResult->length( nbElements ); @@ -2749,7 +3181,7 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() long nbNodes = NbNodes(); aResult->length( nbNodes ); - SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(); + SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true); for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); @@ -2981,21 +3413,21 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) { if ( SMDS_PositionPtr pos = aNode->GetPosition() ) { - aNodePosition->shapeID = pos->GetShapeId(); + aNodePosition->shapeID = aNode->getshapeId(); switch ( pos->GetTypeOfPosition() ) { case SMDS_TOP_EDGE: aNodePosition->shapeType = GEOM::EDGE; aNodePosition->params.length(1); aNodePosition->params[0] = - static_cast( pos.get() )->GetUParameter(); + static_cast( pos )->GetUParameter(); break; case SMDS_TOP_FACE: aNodePosition->shapeType = GEOM::FACE; aNodePosition->params.length(2); aNodePosition->params[0] = - static_cast( pos.get() )->GetUParameter(); + static_cast( pos )->GetUParameter(); aNodePosition->params[1] = - static_cast( pos.get() )->GetVParameter(); + static_cast( pos )->GetVParameter(); break; case SMDS_TOP_VERTEX: aNodePosition->shapeType = GEOM::VERTEX; @@ -3029,11 +3461,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) // try to find node const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); if(aNode) { - SMDS_PositionPtr pos = aNode->GetPosition(); - if(!pos) - return -1; - else - return pos->GetShapeId(); + return aNode->getshapeId(); } return -1; @@ -3351,6 +3779,7 @@ void SMESH_Mesh_i::CreateGroupServants() { SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + set addedIDs; ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups(); while ( groupIt->more() ) { @@ -3360,6 +3789,7 @@ void SMESH_Mesh_i::CreateGroupServants() map::iterator it = _mapGroups.find(anId); if ( it != _mapGroups.end() && !CORBA::is_nil( it->second )) continue; + addedIDs.insert( anId ); SMESH_GroupBase_i* aGroupImpl; TopoDS_Shape shape; @@ -3385,12 +3815,23 @@ void SMESH_Mesh_i::CreateGroupServants() int nextId = _gen_i->RegisterObject( groupVar ); if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); - // publishing of the groups in the study + // publishing the groups in the study if ( !aStudy->_is_nil() ) { GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape ); _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName()); } } + if ( !addedIDs.empty() ) + { + // python dump + set::iterator id = addedIDs.begin(); + for ( ; id != addedIDs.end(); ++id ) + { + map::iterator it = _mapGroups.find(*id); + int i = std::distance( _mapGroups.begin(), it ); + TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]"; + } + } } //============================================================================= @@ -3518,6 +3959,40 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() return aResult._retn(); } +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes() +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + types->length( 4 ); + int nbTypes = 0; + if (_impl->NbEdges()) + types[nbTypes++] = SMESH::EDGE; + if (_impl->NbFaces()) + types[nbTypes++] = SMESH::FACE; + if (_impl->NbVolumes()) + types[nbTypes++] = SMESH::VOLUME; + if (_impl->Nb0DElements()) + types[nbTypes++] = SMESH::ELEM0D; + types->length( nbTypes ); + + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : Returns self +//======================================================================= + +SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() +{ + return SMESH::SMESH_Mesh::_duplicate( _this() ); +} + //============================================================================= /*! * \brief Returns statistic of mesh elements @@ -3862,10 +4337,9 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() */ //============================================================================= -static void findCommonSubMesh - (list& theSubMeshList, - const SMESH_subMesh* theSubMesh, - set& theCommon ) +static void findCommonSubMesh (list& theSubMeshList, + const SMESH_subMesh* theSubMesh, + set& theCommon ) { if ( !theSubMesh ) return; @@ -3939,10 +4413,9 @@ static void findCommonSubMesh */ //============================================================================= -void SMESH_Mesh_i::convertMeshOrder -(const TListOfListOfInt& theIdsOrder, - SMESH::submesh_array_array& theResOrder, - const bool theIsDump) +void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, + SMESH::submesh_array_array& theResOrder, + const bool theIsDump) { int nbSet = theIdsOrder.size(); TPythonDump aPythonDump; // prevent dump of called methods @@ -3988,3 +4461,94 @@ void SMESH_Mesh_i::convertMeshOrder aPythonDump << " = " << _this() << ".GetMeshOrder()"; } } + +//================================================================================ +// +// Implementation of SMESH_MeshPartDS +// +SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): + SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true) +{ + SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + + _meshDS = mesh_i->GetImpl().GetMeshDS(); + + SetPersistentId( _meshDS->GetPersistentId() ); + + if ( mesh_i == SMESH::DownCast( meshPart )) + { + // is the whole mesh + myInfo = _meshDS->GetMeshInfo(); // copy mesh info; + // copy groups + set& myGroupSet = const_cast&>( GetGroups() ); + myGroupSet = _meshDS->GetGroups(); + } + else + { + TMeshInfo tmpInfo; + SMESH::long_array_var anIDs = meshPart->GetIDs(); + SMESH::array_of_ElementType_var types = meshPart->GetTypes(); + if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes + { + for (int i=0; i < anIDs->length(); i++) + if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i])) + if ( _elements[ SMDSAbs_Node ].insert( n ).second ) + tmpInfo.Add( n ); + } + else + { + for (int i=0; i < anIDs->length(); i++) + if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i])) + if ( _elements[ e->GetType() ].insert( e ).second ) + { + tmpInfo.Add( e ); + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + while ( nIt->more() ) + { + const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next(); + if ( _elements[ SMDSAbs_Node ].insert( n ).second ) + tmpInfo.Add( n ); + } + } + } + myInfo = tmpInfo; + + _meshDS = 0; // to enforce iteration on _elements and _nodes + } +} +SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const +{ + typedef SMDS_SetIterator TIter; + if ( type == SMDSAbs_All && !_meshDS ) + { + typedef vector< SMDS_ElemIteratorPtr > TIterVec; + TIterVec iterVec; + for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i ) + if ( !_elements[i].empty() && i != SMDSAbs_Node ) + iterVec.push_back + ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() ))); + + typedef SMDS_IteratorOnIterators TIterOnIters; + return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec )); + } + return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr + ( new TIter( _elements[type].begin(), _elements[type].end() )); +} +#define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \ + iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \ + { \ + typedef SMDS_SetIterator TIter; \ + return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \ + ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \ + } +_GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node ) +_GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement) +_GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge ) +_GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face ) +_GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume) +#undef _GET_ITER_DEFINE +// +// END Implementation of SMESH_MeshPartDS +// +//================================================================================