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=ee7160486460717571ee521be25f589dd2f4f8f9;hp=2e4d1772c2a1bd5c01ea74c750e27528eda85aeb;hb=be0348c630bec8c50d15094deeec95f5cc2d7a8b;hpb=bd4e115a78b52e3fbc016e5e30bb0e19b2a9e7d6 diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 2e4d1772c..ee7160486 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 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 @@ -6,7 +6,7 @@ // 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. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,35 +26,44 @@ #include "SMESH_Mesh_i.hxx" #include "DriverMED_R_SMESHDS_Mesh.h" +#include "DriverMED_W_Field.h" #include "DriverMED_W_SMESHDS_Mesh.h" +#include "MED_Factory.hxx" #include "SMDS_EdgePosition.hxx" #include "SMDS_ElemIterator.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_IteratorOnIterators.hxx" +#include "SMDS_MeshGroup.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Command.hxx" #include "SMESHDS_CommandType.hxx" +#include "SMESHDS_Group.hxx" #include "SMESHDS_GroupOnGeom.hxx" +#include "SMESH_Controls.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_MeshAlgos.hxx" #include "SMESH_MeshEditor.hxx" #include "SMESH_MeshEditor_i.hxx" +#include "SMESH_MeshPartDS.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_PreMeshInfo.hxx" #include "SMESH_PythonDump.hxx" #include "SMESH_subMesh_i.hxx" #include +#include +#include #include -#include #include #include #include + #include +#include // OCCT Includes #include @@ -62,23 +71,30 @@ #include #include #include +#include #include #include #include #include #include #include -#include -#include #include +#include +#include // STL Includes #include #include #include #include + #include +// to pass CORBA exception through SMESH_TRY +#define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; } + +#include "SMESH_TryCatch.hxx" // include after OCCT headers! + #ifdef _DEBUG_ static int MYDEBUG = 0; #else @@ -90,10 +106,6 @@ using SMESH::TPythonDump; int SMESH_Mesh_i::_idGenerator = 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 - //============================================================================= /*! * Constructor @@ -106,11 +118,14 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, : SALOME::GenericObj_i( thePOA ) { MESSAGE("SMESH_Mesh_i"); - _impl = NULL; - _gen_i = gen_i; - _id = _idGenerator++; - _studyId = studyId; - _preMeshInfo = NULL; + _impl = NULL; + _gen_i = gen_i; + _id = _idGenerator++; + _studyId = studyId; + _editor = NULL; + _previewEditor = NULL; + _preMeshInfo = NULL; + _mainShapeTick = 0; } //============================================================================= @@ -123,50 +138,42 @@ SMESH_Mesh_i::~SMESH_Mesh_i() { 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->myMeshServant = 0; + for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) + if (SMESH_GroupBase_i* aGroup = SMESH::DownCast(itGr->second)) + { aGroup->UnRegister(); + SMESH::SMESH_GroupBase_var( itGr->second ); } - } _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) { + for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) + if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast( itSM->second )) + { aSubMesh->UnRegister(); + SMESH::SMESH_subMesh_var( itSM->second ); } - } _mapSubMeshIor.clear(); - // destroy hypotheses + // destroy hypotheses. _mapHypo contains all hyps ever been assigned 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(); - } + if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast( itH->second )) + if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first )) + if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp )) + hyp_i->UnRegister(); + + SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object } _mapHypo.clear(); -#endif + delete _editor; _editor = NULL; + delete _previewEditor; _previewEditor = NULL; delete _impl; _impl = NULL; - - if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL; + delete _preMeshInfo; _preMeshInfo = NULL; } //============================================================================= @@ -190,7 +197,9 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject ) THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } // to track changes of GEOM groups - addGeomGroupData( theShapeObject, _this() ); + SMESH::SMESH_Mesh_var mesh = _this(); + addGeomGroupData( theShapeObject, mesh ); + _mainShapeTick = theShapeObject->GetTick(); } //================================================================================ @@ -273,12 +282,14 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) try { _impl->Clear(); - CheckGeomGroupModif(); // issue 20145 + //CheckGeomGroupModif(); // issue 20145 } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } - TPythonDump() << _this() << ".Clear()"; + _impl->GetMeshDS()->Modified(); + + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()"; } //================================================================================ @@ -300,11 +311,14 @@ void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID) catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } + _impl->GetMeshDS()->Modified(); + + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )"; } //============================================================================= /*! - * + * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus */ //============================================================================= @@ -321,6 +335,8 @@ static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus) res = SMESH::DRS_WARN_RENUMBER; break; case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM: res = SMESH::DRS_WARN_SKIP_ELEM; break; + case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING: + res = SMESH::DRS_WARN_DESCENDING; break; case DriverMED_R_SMESHDS_Mesh::DRS_FAIL: default: res = SMESH::DRS_FAIL; break; @@ -328,6 +344,30 @@ static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus) return res; } +//============================================================================= +/*! + * Convert ::SMESH_ComputeError to SMESH::ComputeError + */ +//============================================================================= + +static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr ) +{ + SMESH::ComputeError_var errVar = new SMESH::ComputeError(); + errVar->subShapeID = -1; + errVar->hasBadMesh = false; + + if ( !errorPtr || errorPtr->IsOK() ) + { + errVar->code = SMESH::COMPERR_OK; + } + else + { + errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName ); + errVar->comment = errorPtr->myComment.c_str(); + } + return errVar._retn(); +} + //============================================================================= /*! * ImportMEDFile @@ -357,9 +397,12 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) int major, minor, release; if( !MED::getMEDVersion( theFileName, major, minor, release ) ) major = minor = release = -1; - _medFileInfo = new SALOME_MED::MedFileInfo(); + _medFileInfo = new SMESH::MedFileInfo(); _medFileInfo->fileName = theFileName; _medFileInfo->fileSize = 0; + _medFileInfo->major = major; + _medFileInfo->minor = minor; + _medFileInfo->release = release; #ifdef WIN32 struct _stati64 d; if ( ::_stati64( theFileName, &d ) != -1 ) @@ -368,9 +411,6 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) if ( ::stat64( theFileName, &d ) != -1 ) #endif _medFileInfo->fileSize = d.st_size; - _medFileInfo->major = major; - _medFileInfo->minor = minor; - _medFileInfo->release = release; return ConvertDriverMEDReadStatus(status); } @@ -412,7 +452,7 @@ SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileNa char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits) { string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version), - nbDigits); + nbDigits); return CORBA::string_dup( ver.c_str() ); } @@ -427,11 +467,15 @@ char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nb int SMESH_Mesh_i::ImportUNVFile( const char* theFileName ) throw ( SALOME::SALOME_Exception ) { + SMESH_TRY; + // Read mesh with name = into SMESH_Mesh _impl->UNVToMesh( theFileName ); CreateGroupServants(); + SMESH_CATCH( SMESH::throwCorbaException ); + return 1; } @@ -445,12 +489,57 @@ int SMESH_Mesh_i::ImportUNVFile( const char* theFileName ) int SMESH_Mesh_i::ImportSTLFile( const char* theFileName ) throw ( SALOME::SALOME_Exception ) { + SMESH_TRY; + // Read mesh with name = into SMESH_Mesh _impl->STLToMesh( theFileName ); + SMESH_CATCH( SMESH::throwCorbaException ); + return 1; } +//================================================================================ +/*! + * \brief Function used in SMESH_CATCH by ImportGMFFile() + */ +//================================================================================ + +namespace +{ + SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText) + { + return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText ); + } +} + +//================================================================================ +/*! + * \brief Imports data from a GMF file and returns an error description + */ +//================================================================================ + +SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName, + bool theMakeRequiredGroups ) + throw (SALOME::SALOME_Exception) +{ + SMESH_ComputeErrorPtr error; + +#undef SMESH_CAUGHT +#define SMESH_CAUGHT error = + SMESH_TRY; + + error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups ); + + SMESH_CATCH( exceptionToComputeError ); +#undef SMESH_CAUGHT +#define SMESH_CAUGHT + + CreateGroupServants(); + + return ConvertComputeError( error ); +} + //============================================================================= /*! * @@ -502,21 +591,24 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp ); + SMESH::SMESH_Mesh_var mesh( _this() ); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) - _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(), - aSubShapeObject, anHyp ); - + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp ); + } if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status ); // Update Python script - if(_impl->HasShapeToMesh()) { - TPythonDump() << "status = " << _this() << ".AddHypothesis( " + //if(_impl->HasShapeToMesh()) + { + TPythonDump() << "status = " << mesh << ".AddHypothesis( " << aSubShapeObject << ", " << anHyp << " )"; } - else { - TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )"; - } - + // else { + // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )"; + // } + return ConvertHypothesisStatus(status); } @@ -527,19 +619,16 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr //============================================================================= SMESH_Hypothesis::Hypothesis_Status - SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, - SMESH::SMESH_Hypothesis_ptr anHyp) +SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, + SMESH::SMESH_Hypothesis_ptr anHyp) { if(MYDEBUG) MESSAGE("addHypothesis"); - if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", - SALOME::BAD_PARAM); + if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh()) + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM); - SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); - if (CORBA::is_nil(myHyp)) - THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", - SALOME::BAD_PARAM); + if (CORBA::is_nil( anHyp )) + THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM); SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; try @@ -551,18 +640,16 @@ SMESH_Hypothesis::Hypothesis_Status else myLocSubShape = _impl->GetShapeToMesh(); - int hypId = myHyp->GetId(); + const int hypId = anHyp->GetId(); status = _impl->AddHypothesis(myLocSubShape, hypId); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) { - _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp ); -#ifdef WITHGENERICOBJ - _mapHypo[hypId]->Register(); -#endif + _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp ); + anHyp->Register(); // assure there is a corresponding submesh if ( !_impl->IsMainShape( myLocSubShape )) { int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() ) - createSubMesh( aSubShapeObject ); + SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject )); } } } @@ -581,28 +668,27 @@ SMESH_Hypothesis::Hypothesis_Status SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, SMESH::SMESH_Hypothesis_ptr anHyp) - throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp ); + SMESH::SMESH_Mesh_var mesh = _this(); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) - _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(), - aSubShapeObject, anHyp ); - - // Update Python script - // Update Python script - if(_impl->HasShapeToMesh()) { - TPythonDump() << "status = " << _this() << ".RemoveHypothesis( " - << aSubShapeObject << ", " << anHyp << " )"; + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp ); } - else { - TPythonDump() << "status = " << _this() << ".RemoveHypothesis( " + // Update Python script + if(_impl->HasShapeToMesh()) + TPythonDump() << "status = " << mesh << ".RemoveHypothesis( " + << aSubShapeObject << ", " << anHyp << " )"; + else + TPythonDump() << "status = " << mesh << ".RemoveHypothesis( " << anHyp << " )"; - } return ConvertHypothesisStatus(status); } @@ -618,13 +704,11 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, SMESH::SMESH_Hypothesis_ptr anHyp) { if(MYDEBUG) MESSAGE("removeHypothesis()"); - // **** proposer liste de sub-shape (selection multiple) - if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) + if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh()) THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); - SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); - if (CORBA::is_nil(myHyp)) + if (CORBA::is_nil( anHyp )) THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM); SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; @@ -632,15 +716,18 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, { TopoDS_Shape myLocSubShape; //use PseudoShape in case if mesh has no shape - if(HasShapeToMesh()) - myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject); + if( _impl->HasShapeToMesh() ) + myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject ); else myLocSubShape = _impl->GetShapeToMesh(); - int hypId = myHyp->GetId(); + const int hypId = anHyp->GetId(); status = _impl->RemoveHypothesis(myLocSubShape, hypId); -// if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes -// _mapHypo.erase( hypId ); + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) + { + // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes + anHyp->UnRegister(); + } } catch(SALOME_Exception & S_ex) { @@ -656,7 +743,7 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, //============================================================================= SMESH::ListOfHypothesis * - SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) +SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -674,12 +761,14 @@ throw(SALOME::SALOME_Exception) int i = 0, n = aLocalList.size(); aList->length( n ); - for ( list::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) { - SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt); - if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() ) - aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] ); + list::const_iterator aHyp = aLocalList.begin(); + std::map::iterator id_hypptr; + for ( ; i < n && aHyp != aLocalList.end(); aHyp++ ) + { + id_hypptr = _mapHypo.find( (*aHyp)->GetID() ); + if ( id_hypptr != _mapHypo.end() ) + aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second ); } - aList->length( i ); } catch(SALOME_Exception & S_ex) { @@ -720,7 +809,7 @@ SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Excepti // Update Python script if ( !_mapSubMeshIor.empty() ) - aPythonDump << " ] = " << _this() << ".GetSubMeshes()"; + aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()"; return aList._retn(); } @@ -730,18 +819,17 @@ SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Excepti * */ //============================================================================= + SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, const char* theName ) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_Mesh_i::GetSubMesh"); if (CORBA::is_nil(aSubShapeObject)) - THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", - SALOME::BAD_PARAM); + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); SMESH::SMESH_subMesh_var subMesh; - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this()); + SMESH::SMESH_Mesh_var aMesh = _this(); try { TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject); @@ -760,13 +848,14 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap // create a new subMesh object servant if there is none for the shape if ( subMesh->_is_nil() ) subMesh = createSubMesh( aSubShapeObject ); - if ( _gen_i->CanPublishInStudy( subMesh )) { - SALOMEDS::SObject_var aSO = - _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh, - subMesh, aSubShapeObject, theName ); + if ( _gen_i->CanPublishInStudy( subMesh )) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName ); if ( !aSO->_is_nil()) { // Update Python script - TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( " + TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( " << aSubShapeObject << ", '" << theName << "' )"; } } @@ -784,36 +873,43 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap //============================================================================= void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh"); + SMESH_TRY; + if ( theSubMesh->_is_nil() ) return; GEOM::GEOM_Object_var aSubShapeObject; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { // Remove submesh's SObject - SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh ); + SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh ); if ( !anSO->_is_nil() ) { long aTag = SMESH_Gen_i::GetRefOnShapeTag(); - SALOMEDS::SObject_var anObj, aRef; - if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) ) - aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() ); - -// if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617) -// aSubShapeObject = theSubMesh->GetSubShape(); + SALOMEDS::SObject_wrap anObj, aRef; + if ( anSO->FindSubObject( aTag, anObj.inout() ) && + anObj->ReferencedObject( aRef.inout() )) + { + CORBA::Object_var obj = aRef->GetObject(); + aSubShapeObject = GEOM::GEOM_Object::_narrow( obj ); + } + // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617) + // aSubShapeObject = theSubMesh->GetSubShape(); - aStudy->NewBuilder()->RemoveObjectWithChildren( anSO ); + SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder(); + builder->RemoveObjectWithChildren( anSO ); // Update Python script - TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )"; } } if ( removeSubMesh( theSubMesh, aSubShapeObject.in() )) if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); + + SMESH_CATCH( SMESH::throwCorbaException ); } //============================================================================= @@ -824,7 +920,7 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType, const char* theName ) - throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -833,20 +929,20 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType SMESH::SMESH_Group_var aNewGroup = SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName )); - 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()) { + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName); + if ( !aSO->_is_nil()) // Update Python script - TPythonDump() << aSO << " = " << _this() << ".CreateGroup( " + TPythonDump() << aSO << " = " << mesh << ".CreateGroup( " << theElemType << ", '" << theName << "' )"; - } } return aNewGroup._retn(); } - //============================================================================= /*! * @@ -856,7 +952,7 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, const char* theName, GEOM::GEOM_Object_ptr theGeomObj) - throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -867,18 +963,18 @@ SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj ); if ( !aShape.IsNull() ) { - aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow - ( createGroup( theElemType, theName, aShape )); + aNewGroup = + SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape )); - if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { - SALOMEDS::SObject_var aSO = - _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), - aNewGroup, theGeomObj, theName); - if ( !aSO->_is_nil()) { - // Update Python script - TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM(" + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName ); + if ( !aSO->_is_nil()) + TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( " << theElemType << ", '" << theName << "', " << theGeomObj << " )"; - } } } @@ -899,7 +995,7 @@ SMESH::SMESH_GroupOnFilter_ptr SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, const char* theName, SMESH::Filter_ptr theFilter ) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -921,16 +1017,15 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, 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(" + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName ); + + if ( !aSO->_is_nil()) + pd << aSO << " = " << mesh << ".CreateGroupFromFilter( " << theElemType << ", '" << theName << "', " << theFilter << " )"; - } } - return aNewGroup._retn(); } @@ -941,31 +1036,36 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, //============================================================================= void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { if ( theGroup->_is_nil() ) return; - SMESH_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + SMESH_TRY; + + SMESH_GroupBase_i* aGroup = SMESH::DownCast( theGroup ); if ( !aGroup ) return; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); - - if ( !aGroupSO->_is_nil() ) { + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) + { + SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); + if ( !aGroupSO->_is_nil() ) + { // Update Python script - TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )"; // Remove group's SObject - aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO ); + SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder(); + builder->RemoveObjectWithChildren( aGroupSO ); } } // Remove the group from SMESH data structures removeGroup( aGroup->GetLocalID() ); + + SMESH_CATCH( SMESH::throwCorbaException ); } //============================================================================= @@ -977,39 +1077,35 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception) { + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( theGroup->_is_nil() ) return; - SMESH_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); - if ( !aGroup ) - return; - - SMESH::long_array_var anIds = aGroup->GetListOfID(); - SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); + // Remove contents + SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup ); + SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() ); + while ( elemIt->more() ) + _impl->GetMeshDS()->RemoveElement( elemIt->next() ); - TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup() + TPythonDump pyDump; // Supress dump from RemoveGroup() - // Remove contents - if ( aGroup->GetType() == SMESH::NODE ) - aMeshEditor->RemoveNodes( anIds ); - else - aMeshEditor->RemoveElements( anIds ); + // Update Python script (theGroup must be alive for this) + pyDump << SMESH::SMESH_Mesh_var(_this()) + << ".RemoveGroupWithContents( " << theGroup << " )"; // Remove group RemoveGroup( theGroup ); - // Update Python script - pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; + SMESH_CATCH( SMESH::throwCorbaException ); } //================================================================================ /*! * \brief Get the list of groups existing in the mesh - * \retval SMESH::ListOfGroups * - list of groups + * \retval SMESH::ListOfGroups * - list of groups */ //================================================================================ @@ -1022,30 +1118,27 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception) // Python Dump TPythonDump aPythonDump; - if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []" + if ( !_mapGroups.empty() ) + { aPythonDump << "[ "; - - try { - aList->length( _mapGroups.size() ); - int i = 0; - map::iterator it = _mapGroups.begin(); - for ( ; it != _mapGroups.end(); it++ ) { - if ( CORBA::is_nil( it->second )) continue; - aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second ); - // Python Dump - if (i > 1) aPythonDump << ", "; - aPythonDump << it->second; + try { + aList->length( _mapGroups.size() ); + int i = 0; + map::iterator it = _mapGroups.begin(); + for ( ; it != _mapGroups.end(); it++ ) { + if ( CORBA::is_nil( it->second )) continue; + aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second ); + // Python Dump + if (i > 1) aPythonDump << ", "; + aPythonDump << it->second; + } + aList->length( i ); } - aList->length( i ); - } - catch(SALOME_Exception & S_ex) { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()"; } - - // Update Python script - if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []" - aPythonDump << " ] = " << _this() << ".GetGroups()"; - return aList._retn(); } @@ -1062,204 +1155,170 @@ CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception) } //============================================================================= -/*! UnionGroups - * New group is created. All mesh elements that are - * present in initial groups are added to the new one +/*! + * New group including all mesh elements present in initial groups is created. */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, - const char* theName ) + const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - try - { - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - - // Create Union - SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aResMap; - - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - aResMap.Add( anIds1[ i1 ] ); - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - aResMap.Add( anIds2[ i2 ] ); - - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aResMap.Extent() ); + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types", + SALOME::BAD_PARAM); + TPythonDump pyDump; - int resI = 0; - TColStd_MapIteratorOfMapOfInteger anIter( aResMap ); - for( ; anIter.More(); anIter.Next() ) - aResIds[ resI++ ] = anIter.Key(); + // Create Union + aResGrp = CreateGroup( theGroup1->GetType(), theName ); + if ( aResGrp->_is_nil() ) + return SMESH::SMESH_Group::_nil(); - aResGrp->Add( aResIds ); + aResGrp->AddFrom( theGroup1 ); + aResGrp->AddFrom( theGroup2 ); - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )"; - // Update Python script - TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + SMESH_CATCH( SMESH::throwCorbaException ); - return aResGrp._retn(); - } - catch( ... ) - { - return SMESH::SMESH_Group::_nil(); - } + return aResGrp._retn(); } //============================================================================= /*! - \brief Union list of groups. New group is created. All mesh elements that are - present in initial groups are added to the new one. - \param theGroups list of groups - \param theName name of group to be created - \return pointer on the group -*/ + * \brief New group including all mesh elements present in initial groups is created. + * \param theGroups list of groups + * \param theName name of group to be created + * \return pointer to the new group + */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups, const char* theName ) -throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - try + SMESH_TRY; + + // check types + SMESH::ElementType aType = SMESH::ALL; + for ( int g = 0, n = theGroups.length(); g < n; g++ ) { - vector< int > anIds; - SMESH::ElementType aType = SMESH::ALL; - for ( int g = 0, n = theGroups.length(); g < n; g++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; + SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + if ( aType == SMESH::ALL ) + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types", + SALOME::BAD_PARAM); + } + if ( aType == SMESH::ALL ) + return SMESH::SMESH_Group::_nil(); - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } + TPythonDump pyDump; - // unite ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - anIds.push_back( aCurrId ); - } - } + // Create Union + aResGrp = CreateGroup( aType, theName ); + if ( aResGrp->_is_nil() ) + return SMESH::SMESH_Group::_nil(); - // Create group - SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); - - //NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; iAddFrom( aGrp ); + if ( g > 0 ) pyDump << ", "; + pyDump << aGrp; } - aResGrp->Add( aResIds ); - - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); + } + pyDump << " ], '" << theName << "' )"; - // Update Python script - - TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + SMESH_CATCH( SMESH::throwCorbaException ); - return aResGrp._retn(); - } - catch( ... ) - { - return SMESH::SMESH_Group::_nil(); - } + return aResGrp._retn(); } //============================================================================= -/*! IntersectGroups +/*! * New group is created. All mesh elements that are * present in both initial groups are added to the new one. */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, - const char* theName ) + const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types", + SALOME::BAD_PARAM); + TPythonDump pyDump; // Create Intersection - SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName ); + aResGrp = CreateGroup( theGroup1->GetType(), theName ); if ( aResGrp->_is_nil() ) - return aResGrp; - - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aMap1; - - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - aMap1.Add( anIds1[ i1 ] ); - - TColStd_SequenceOfInteger aSeq; - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - if ( aMap1.Contains( anIds2[ i2 ] ) ) - aSeq.Append( anIds2[ i2 ] ); - - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); + return aResGrp._retn(); - for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - aResGrp->Add( aResIds ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() ) + { + SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + if ( groupDS2->Contains( e )) + resGroupDS->SMDSGroup().Add( e ); + } + } // Update Python script - TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( " - << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( " + << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; + + SMESH_CATCH( SMESH::throwCorbaException ); return aResGrp._retn(); } @@ -1278,143 +1337,136 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - try + // check types and get SMESHDS_GroupBase's + SMESH::ElementType aType = SMESH::ALL; + vector< SMESHDS_GroupBase* > groupVec; + for ( int g = 0, n = theGroups.length(); g < n; g++ ) { - NCollection_DataMap< int, int > anIdToCount; - SMESH::ElementType aType = SMESH::ALL; - for ( int g = 0, n = theGroups.length(); g < n; g++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else + SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + if ( aType == SMESH::ALL ) + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types", + SALOME::BAD_PARAM); + + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); + if ( grpDS->IsEmpty() ) + { + groupVec.clear(); + break; + } + groupVec.push_back( grpDS ); } + } + if ( aType == SMESH::ALL ) // all groups are nil + return SMESH::SMESH_Group::_nil(); - // calculates number of occurance ids in groups - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - if ( !anIdToCount.IsBound( aCurrId ) ) - anIdToCount.Bind( aCurrId, 1 ); - else - anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1; - } - } - - // create map of ids - int nbGrp = theGroups.length(); - 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.push_back( aCurrId ); - } + TPythonDump pyDump; - // Create group - SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); - - //NCollection_Map< int >::Iterator aListIter( anIds ); - for ( int i = 0; iAdd( aResIds ); - - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - - // Update Python script - - TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + // Create a group + aResGrp = CreateGroup( aType, theName ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( !resGroupDS || groupVec.empty() ) return aResGrp._retn(); - } - catch( ... ) + + // Fill the group + size_t i, nb = groupVec.size(); + SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements(); + while ( elemIt1->more() ) { - return SMESH::SMESH_Group::_nil(); + const SMDS_MeshElement* e = elemIt1->next(); + bool inAll = true; + for ( i = 1; ( i < nb && inAll ); ++i ) + inAll = groupVec[i]->Contains( e ); + + if ( inAll ) + resGroupDS->SMDSGroup().Add( e ); } + + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )"; + + SMESH_CATCH( SMESH::throwCorbaException ); + + return aResGrp._retn(); } //============================================================================= -/*! CutGroups +/*! * New group is created. All mesh elements that are present in - * main group but do not present in tool group are added to the new one + * a main group but is not present in a tool group are added to the new one */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types", + SALOME::BAD_PARAM); + TPythonDump pyDump; - // Perform Cutting - SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName ); + aResGrp = CreateGroup( theGroup1->GetType(), theName ); if ( aResGrp->_is_nil() ) - return aResGrp; - - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aMap2; - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - aMap2.Add( anIds2[ i2 ] ); - - TColStd_SequenceOfInteger aSeq; - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - if ( !aMap2.Contains( anIds1[ i1 ] ) ) - aSeq.Append( anIds1[ i1 ] ); - - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); + return aResGrp._retn(); - for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - aResGrp->Add( aResIds ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( groupDS1 && groupDS2 && resGroupDS ) + { + SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + if ( !groupDS2->Contains( e )) + resGroupDS->SMDSGroup().Add( e ); + } + } // Update Python script - TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( " + << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; + + SMESH_CATCH( SMESH::throwCorbaException ); return aResGrp._retn(); } @@ -1435,124 +1487,115 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - try - { - set< int > aToolIds; - SMESH::ElementType aType = SMESH::ALL; - int g, n; - // iterate through tool groups - for ( g = 0, n = theToolGroups.length(); g < n; g++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; + // check types and get SMESHDS_GroupBase's + SMESH::ElementType aType = SMESH::ALL; + vector< SMESHDS_GroupBase* > toolGroupVec; + vector< SMDS_ElemIteratorPtr > mainIterVec; - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } + for ( int g = 0, n = theMainGroups.length(); g < n; g++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + if ( aType == SMESH::ALL ) + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", + SALOME::BAD_PARAM); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + if ( !grpDS->IsEmpty() ) + mainIterVec.push_back( grpDS->GetElements() ); + } + if ( aType == SMESH::ALL ) // all main groups are nil + return SMESH::SMESH_Group::_nil(); + if ( mainIterVec.empty() ) // all main groups are empty + return aResGrp._retn(); - // unite tool ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - aToolIds.insert( aCurrId ); - } - } + for ( int g = 0, n = theToolGroups.length(); g < n; g++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", + SALOME::BAD_PARAM); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + toolGroupVec.push_back( grpDS ); + } - vector< int > anIds; // result + TPythonDump pyDump; - // Iterate through main group - for ( g = 0, n = theMainGroups.length(); g < n; g++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; + // Create a group + aResGrp = CreateGroup( aType, theName ); - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( !resGroupDS ) + return aResGrp._retn(); - // unite tool ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - if ( !aToolIds.count( aCurrId ) ) - anIds.push_back( aCurrId ); - } - } + // Fill the group + size_t i, nb = toolGroupVec.size(); + SMDS_ElemIteratorPtr mainElemIt + ( new SMDS_IteratorOnIterators + < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec )); + while ( mainElemIt->more() ) + { + const SMDS_MeshElement* e = mainElemIt->next(); + bool isIn = false; + for ( i = 0; ( i < nb && !isIn ); ++i ) + isIn = toolGroupVec[i]->Contains( e ); - // Create group - SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); - - for (int i=0; iAdd( aResIds ); + if ( !isIn ) + resGroupDS->SMDSGroup().Add( e ); + } - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".CutListOfGroups( " << theMainGroups + << theToolGroups << ", '" << theName << "' )"; - // Update Python script + SMESH_CATCH( SMESH::throwCorbaException ); - TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( " - << &theMainGroups << ", " << &theToolGroups << ", '" - << theName << "' )"; - - return aResGrp._retn(); - } - catch( ... ) - { - return SMESH::SMESH_Group::_nil(); - } + return aResGrp._retn(); } //============================================================================= /*! \brief Create groups of entities from existing groups of superior dimensions - System + System 1) extract all nodes from each group, 2) combine all elements of specified dimension laying on these nodes. \param theGroups list of source groups \param theElemType dimension of elements \param theName name of new group \return pointer on new group + * + IMP 19939 */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, SMESH::ElementType theElemType, const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -1563,141 +1606,74 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType; - try - { - // Create map of nodes from all groups + // Create a group - set< int > aNodeMap; - - for ( int g = 0, n = theGroups.length(); g < n; g++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; + TPythonDump pyDump; - SMESH::ElementType aType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - continue; - else if ( aType == SMESH::NODE ) - { - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId ); - if ( aNode ) - aNodeMap.insert( aNode->GetID() ); - } - } - else - { - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId ); - if ( !anElem ) - continue; - SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator(); - while( aNodeIter->more() ) - { - const SMDS_MeshNode* aNode = - dynamic_cast( aNodeIter->next() ); - if ( aNode ) - aNodeMap.insert( aNode->GetID() ); - } - } - } - } + aResGrp = CreateGroup( theElemType, theName ); + if ( aResGrp->_is_nil() ) + return SMESH::SMESH_Group::_nil(); + + SMESHDS_GroupBase* groupBaseDS = + SMESH::DownCast( aResGrp )->GetGroupDS(); + SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup(); + + for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups + { + SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; - // Get result identifiers + groupBaseDS = SMESH::DownCast( aGrp )->GetGroupDS(); + SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements(); - vector< int > aResultIds; - if ( theElemType == SMESH::NODE ) + if ( theElemType == SMESH::NODE ) // get all nodes of elements { - //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - set::iterator iter = aNodeMap.begin(); - for ( ; iter != aNodeMap.end(); iter++ ) - aResultIds.push_back( *iter); + while ( elIt->more() ) { + const SMDS_MeshElement* el = elIt->next(); + SMDS_ElemIteratorPtr nIt = el->nodesIterator(); + while ( nIt->more() ) + resGroupCore.Add( nIt->next() ); + } } - else + else // get elements of theElemType based on nodes of every element of group { - // Create list of elements of given dimension constructed on the nodes - 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( *iter ) ); - if ( !aNode ) - continue; - - SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType ); - while( anElemIter->more() ) - { - const SMDS_MeshElement* anElem = - dynamic_cast( anElemIter->next() ); - if ( anElem && anElem->GetType() == anElemType ) - anElemList.push_back( anElem->GetID() ); - } - } - - // check whether all nodes of elements are present in nodes map - for (int i=0; i< anElemList.size(); i++) + while ( elIt->more() ) { - const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] ); - if ( !anElem ) - continue; - - bool isOk = true; - SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator(); - while( aNodeIter->more() ) + const SMDS_MeshElement* el = elIt->next(); // an element of group + TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() ); + TIDSortedElemSet checkedElems; + SMDS_ElemIteratorPtr nIt = el->nodesIterator(); + while ( nIt->more() ) { - const SMDS_MeshNode* aNode = - dynamic_cast( aNodeIter->next() ); - if ( !aNode || !aNodeMap.count( aNode->GetID() ) ) + const SMDS_MeshNode* n = static_cast( nIt->next() ); + SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType ); + // check nodes of elements of theElemType around el + while ( elOfTypeIt->more() ) { - isOk = false; - break; + const SMDS_MeshElement* elOfType = elOfTypeIt->next(); + if ( !checkedElems.insert( elOfType ).second ) continue; + + SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator(); + bool allNodesOK = true; + while ( nIt2->more() && allNodesOK ) + allNodesOK = elNodes.count( nIt2->next() ); + if ( allNodesOK ) + resGroupCore.Add( elOfType ); } - } - if ( isOk ) - aResultIds.push_back( anElem->GetID() ); + } } } + } - // Create group - - SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aResultIds.size() ); - - for (int i=0; i< aResultIds.size(); i++) - aResIds[ i ] = aResultIds[i]; - aResGrp->Add( aResIds ); - - // Remove strings corresponding to group creation - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this()) + << ".CreateDimGroup( " + << theGroups << ", " << theElemType << ", '" << theName << "' )"; - // Update Python script - - TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( " - << &theGroups << ", " << theElemType << ", '" << theName << "' )"; + SMESH_CATCH( SMESH::throwCorbaException ); - return aResGrp._retn(); - } - catch( ... ) - { - return SMESH::SMESH_Group::_nil(); - } + return aResGrp._retn(); } //================================================================================ @@ -1712,13 +1688,13 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP ) return; // group SO - SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); - SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); if ( groupSO->_is_nil() ) return; // group indices GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); - GEOM::GEOM_IGroupOperations_var groupOp = + GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); @@ -1732,7 +1708,7 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, for ( int i = 0; i < ids->length(); ++i ) groupData._indices.insert( ids[i] ); // SMESH object - groupData._smeshObject = theSmeshObj; + groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj ); } //================================================================================ @@ -1766,7 +1742,7 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) // get geom group SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); if ( study->_is_nil() ) return newShape; // means "not changed" - SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() ); + SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() ); if ( !groupSO->_is_nil() ) { CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO ); @@ -1776,9 +1752,9 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) // get indices of group items set curIndices; GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); - GEOM::GEOM_IGroupOperations_var groupOp = + GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); - GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); + GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); for ( int i = 0; i < ids->length(); ++i ) curIndices.insert( ids[i] ); @@ -1790,10 +1766,10 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) GEOM_Client* geomClient = _gen_i->GetShapeReader(); if ( !geomClient ) return newShape; - TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup ); - geomClient->RemoveShapeFromBuffer( groupIOR ); + CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup ); + geomClient->RemoveShapeFromBuffer( groupIOR.in() ); newShape = _gen_i->GeomObjectToShape( geomGroup ); - } + } if ( newShape.IsNull() ) { // geom group becomes empty - return empty compound @@ -1806,22 +1782,152 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) namespace { - //============================================================================= + //----------------------------------------------------------------------------- /*! * \brief Storage of shape and index used in CheckGeomGroupModif() */ - //============================================================================= struct TIndexedShape { int _index; TopoDS_Shape _shape; TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {} }; + //----------------------------------------------------------------------------- + /*! + * \brief Data to re-create a group on geometry + */ + struct TGroupOnGeomData + { + int _oldID; + int _shapeID; + SMDSAbs_ElementType _type; + std::string _name; + Quantity_Color _color; + }; } + +//============================================================================= +/*! + * \brief Update data if geometry changes + * + * Issue 0022501 + */ +//============================================================================= + +void SMESH_Mesh_i::CheckGeomModif() +{ + if ( !_impl->HasShapeToMesh() ) return; + + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) return; + + GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() ); + if ( mainGO->_is_nil() ) return; + + if ( mainGO->GetType() == GEOM_GROUP ) + { + CheckGeomGroupModif(); + return; + } + if ( mainGO->GetTick() == _mainShapeTick ) + return; + + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) return; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); + if ( geomGen->_is_nil() ) return; + + CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + + // Update data taking into account that + // all sub-shapes change but IDs of sub-shapes remain + + _impl->Clear(); + TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO ); + if ( newShape.IsNull() ) + return; + + _mainShapeTick = mainGO->GetTick(); + + SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); + + // store data of groups on geometry + vector< TGroupOnGeomData > groupsData; + const set& groups = meshDS->GetGroups(); + groupsData.reserve( groups.size() ); + set::const_iterator g = groups.begin(); + for ( ; g != groups.end(); ++g ) + if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g )) + { + TGroupOnGeomData data; + data._oldID = group->GetID(); + data._shapeID = meshDS->ShapeToIndex( group->GetShape() ); + data._type = group->GetType(); + data._name = group->GetStoreName(); + data._color = group->GetColor(); + groupsData.push_back( data ); + } + // store assigned hypotheses + vector< pair< int, THypList > > ids2Hyps; + const ShapeToHypothesis & hyps = meshDS->GetHypotheses(); + for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() ) + { + const TopoDS_Shape& s = s2hyps.Key(); + const THypList& hyps = s2hyps.ChangeValue(); + ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps )); + } + + // change shape to mesh + _impl->ShapeToMesh( TopoDS_Shape() ); + _impl->ShapeToMesh( newShape ); + + // re-assign hypotheses + for ( size_t i = 0; i < ids2Hyps.size(); ++i ) + { + const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first ); + const THypList& hyps = ids2Hyps[i].second; + THypList::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) + _impl->AddHypothesis( s, (*h)->GetID() ); + } + + // restore groups + for ( size_t i = 0; i < groupsData.size(); ++i ) + { + const TGroupOnGeomData& data = groupsData[i]; + + map::iterator i2g = _mapGroups.find( data._oldID ); + if ( i2g == _mapGroups.end() ) continue; + + SMESH_GroupBase_i* gr_i = SMESH::DownCast( i2g->second ); + if ( !gr_i ) continue; + + int id; + SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id, + meshDS->IndexToShape( data._shapeID )); + if ( !g ) + { + _mapGroups.erase( i2g ); + } + else + { + gr_i->changeLocalId( id ); + g->GetGroupDS()->SetColor( data._color ); + } + } + + // update _mapSubMesh + map::iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) + i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first )); + +} + //============================================================================= /*! * \brief Update objects depending on changed geom groups - * + * * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation * issue 0020210: Update of a smesh group after modification of the associated geom group */ @@ -1869,7 +1975,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() if ( !submesh->_is_nil() ) // -------------- Sub mesh --------------------- { int oldID = submesh->GetId(); - if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() ) + if ( !_mapSubMeshIor.count( oldID )) continue; TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape(); @@ -1989,12 +2095,12 @@ void SMESH_Mesh_i::CheckGeomGroupModif() list& hyps = indS_hyps->second; int oldID = geom._index; int newID = meshDS->ShapeToIndex( geom._shape ); - if ( !newID ) - continue; if ( oldID == 1 ) { // main shape newID = 1; geom._shape = newShape; } + if ( !newID ) + continue; for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) _impl->AddHypothesis( geom._shape, (*hypIt)->GetID()); // care of submeshes @@ -2018,10 +2124,10 @@ void SMESH_Mesh_i::CheckGeomGroupModif() if ( _mapGroups.find( oldID ) == _mapGroups.end() ) continue; // get group name - SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] ); - CORBA::String_var name = groupSO->GetName(); + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] ); + CORBA::String_var name = groupSO->GetName(); // update - SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID] ); + SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID] ); int newID; if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape )) group_i->changeLocalId( newID ); @@ -2035,7 +2141,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() // Update icons CORBA::Long newNbEntities = NbNodes() + NbElements(); - list< SALOMEDS::SObject_var > soToUpdateIcons; + list< SALOMEDS::SObject_wrap > soToUpdateIcons; if ( newNbEntities != nbEntities ) { // Add all SObjects with icons to soToUpdateIcons @@ -2050,7 +2156,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second )); } - list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin(); + list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin(); for ( ; so != soToUpdateIcons.end(); ++so ) _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" ); } @@ -2062,24 +2168,25 @@ void SMESH_Mesh_i::CheckGeomGroupModif() //============================================================================= SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup ) + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aGroup; + + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::SMESH_Group_var aGroup; if ( theGroup->_is_nil() ) return aGroup._retn(); - Unexpect aCatch(SALOME_SalomeException); - - SMESH_GroupBase_i* aGroupToRem = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast( theGroup ); if ( !aGroupToRem ) return aGroup._retn(); const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )); - int anId = aGroupToRem->GetLocalID(); + const int anId = aGroupToRem->GetLocalID(); if ( !_impl->ConvertToStandalone( anId ) ) return aGroup._retn(); removeGeomGroupData( theGroup ); @@ -2087,25 +2194,26 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); // remove old instance of group from own map + { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object _mapGroups.erase( anId ); SALOMEDS::StudyBuilder_var builder; - SALOMEDS::SObject_var aGroupSO; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - builder = aStudy->NewBuilder(); + SALOMEDS::SObject_wrap aGroupSO; + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + builder = aStudy->NewBuilder(); aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); - if ( !aGroupSO->_is_nil() ) { - + if ( !aGroupSO->_is_nil() ) + { // remove reference to geometry - SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO); + SALOMEDS::ChildIterator_wrap 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 << " )"; + TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".ConvertToStandalone( " << aGroupSO << " )"; // change icon of Group on Filter if ( isOnFilter ) @@ -2114,28 +2222,28 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase const int isEmpty = ( elemTypes->length() == 0 ); if ( !isEmpty ) { - SALOMEDS::GenericAttribute_var anAttr = + SALOMEDS::GenericAttribute_wrap anAttr = builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" ); - SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr ); + SALOMEDS::AttributePixMap_wrap pm = anAttr; pm->SetPixMap( "ICON_SMESH_TREE_GROUP" ); } } } } - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl ); - aGroupImpl->Register(); - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - // remember new group in own map aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() ); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup ); // register CORBA object for persistence - /*int nextId =*/ _gen_i->RegisterObject( aGroup ); + _gen_i->RegisterObject( aGroup ); + + CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup ); + builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register(); + //aGroup->Register(); + aGroupToRem->UnRegister(); - builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) ); + SMESH_CATCH( SMESH::throwCorbaException ); return aGroup._retn(); } @@ -2149,21 +2257,23 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject ) { if(MYDEBUG) MESSAGE( "createSubMesh" ); - TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject); - + TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject); ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape); - int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); - SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); - SMESH::SMESH_subMesh_var subMesh - = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this()); + const int subMeshId = mySubMesh->GetId(); + + SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); + SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this(); - _mapSubMesh[subMeshId] = mySubMesh; - _mapSubMesh_i[subMeshId] = subMeshServant; - _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh); + _mapSubMesh [subMeshId] = mySubMesh; + _mapSubMesh_i [subMeshId] = subMeshServant; + _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh ); + + subMeshServant->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( subMesh ); - if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId); + if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); } + else { nextId = 0; } // avoid "unused variable" warning // to track changes of GEOM groups addGeomGroupData( theSubShapeObject, subMesh ); @@ -2185,7 +2295,6 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID) return SMESH::SMESH_subMesh::_duplicate( (*it).second ); } - //============================================================================= /*! * @@ -2199,12 +2308,13 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ ) return isHypChanged; + const int subMeshId = theSubMesh->GetId(); + if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617) { - CORBA::Long shapeId = theSubMesh->GetId(); - if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end()) + if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end()) { - TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape(); + TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape(); if ( !S.IsNull() ) { list hyps = _impl->GetHypothesisList( S ); @@ -2229,7 +2339,16 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, } removeGeomGroupData( theSubShapeObject ); } - int subMeshId = theSubMesh->GetId(); + + // remove a servant + std::map::iterator id_smi = _mapSubMesh_i.find( subMeshId ); + if ( id_smi != _mapSubMesh_i.end() ) + id_smi->second->UnRegister(); + + // remove a CORBA object + std::map::iterator id_smptr = _mapSubMeshIor.find( subMeshId ); + if ( id_smptr != _mapSubMeshIor.end() ) + SMESH::SMESH_subMesh_var( id_smptr->second ); _mapSubMesh.erase(subMeshId); _mapSubMesh_i.erase(subMeshId); @@ -2255,7 +2374,10 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType 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() ); + { + CORBA::String_var name = i_gr->second->GetName(); + presentNames.insert( name.in() ); + } do { newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 ); } while ( !presentNames.insert( newName ).second ); @@ -2273,17 +2395,14 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType else aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl ); - aGroupImpl->Register(); - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - - aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() ); + aGroup = aGroupImpl->_this(); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup ); + aGroupImpl->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( aGroup ); - if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); + if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); } + else { nextId = 0; } // avoid "unused variable" warning in release mode // to track changes of GEOM groups if ( !theShape.IsNull() ) { @@ -2306,14 +2425,15 @@ void SMESH_Mesh_i::removeGroup( const int theId ) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" ); if ( _mapGroups.find( theId ) != _mapGroups.end() ) { - SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId]; + SMESH::SMESH_GroupBase_var group = _mapGroups[theId]; _mapGroups.erase( theId ); removeGeomGroupData( group ); - if (! _impl->RemoveGroup( theId )) + if ( !_impl->RemoveGroup( theId )) { // it seems to be a call up from _impl caused by hyp modification (issue 0020918) RemoveGroup( group ); } + group->UnRegister(); } } @@ -2324,57 +2444,57 @@ void SMESH_Mesh_i::removeGroup( const int theId ) //============================================================================= SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) -throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { + SMESH::log_array_var aLog; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::log_array_var aLog; - try{ - list < SMESHDS_Command * >logDS = _impl->GetLog(); - aLog = new SMESH::log_array; - int indexLog = 0; - int lg = logDS.size(); - SCRUTE(lg); - aLog->length(lg); - list < SMESHDS_Command * >::iterator its = logDS.begin(); - while(its != logDS.end()){ - SMESHDS_Command *com = *its; - int comType = com->GetType(); - //SCRUTE(comType); - int lgcom = com->GetNumber(); - //SCRUTE(lgcom); - const list < int >&intList = com->GetIndexes(); - int inum = intList.size(); - //SCRUTE(inum); - list < int >::const_iterator ii = intList.begin(); - const list < double >&coordList = com->GetCoords(); - int rnum = coordList.size(); - //SCRUTE(rnum); - list < double >::const_iterator ir = coordList.begin(); - aLog[indexLog].commandType = comType; - aLog[indexLog].number = lgcom; - aLog[indexLog].coords.length(rnum); - aLog[indexLog].indexes.length(inum); - for(int i = 0; i < rnum; i++){ - aLog[indexLog].coords[i] = *ir; - //MESSAGE(" "<logDS = _impl->GetLog(); + aLog = new SMESH::log_array; + int indexLog = 0; + int lg = logDS.size(); + SCRUTE(lg); + aLog->length(lg); + list < SMESHDS_Command * >::iterator its = logDS.begin(); + while(its != logDS.end()){ + SMESHDS_Command *com = *its; + int comType = com->GetType(); + //SCRUTE(comType); + int lgcom = com->GetNumber(); + //SCRUTE(lgcom); + const list < int >&intList = com->GetIndexes(); + int inum = intList.size(); + //SCRUTE(inum); + list < int >::const_iterator ii = intList.begin(); + const list < double >&coordList = com->GetCoords(); + int rnum = coordList.size(); + //SCRUTE(rnum); + list < double >::const_iterator ir = coordList.begin(); + aLog[indexLog].commandType = comType; + aLog[indexLog].number = lgcom; + aLog[indexLog].coords.length(rnum); + aLog[indexLog].indexes.length(inum); + for(int i = 0; i < rnum; i++){ + aLog[indexLog].coords[i] = *ir; + //MESSAGE(" "<ClearLog(); - } - catch(SALOME_Exception & S_ex){ - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + for(int i = 0; i < inum; i++){ + aLog[indexLog].indexes[i] = *ii; + //MESSAGE(" "<ClearLog(); + + SMESH_CATCH( SMESH::throwCorbaException ); + return aLog._retn(); } @@ -2387,8 +2507,9 @@ throw(SALOME::SALOME_Exception) void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception) { - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog"); + SMESH_TRY; _impl->ClearLog(); + SMESH_CATCH( SMESH::throwCorbaException ); } //============================================================================= @@ -2399,7 +2520,6 @@ void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception) CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception) { - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId"); return _id; } @@ -2475,18 +2595,26 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl) //============================================================================= SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_MeshEditor_var aMeshEdVar; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); // Create MeshEditor - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false ); - SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this(); + if ( !_editor ) + _editor = new SMESH_MeshEditor_i( this, false ); + aMeshEdVar = _editor->_this(); // Update Python script - TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()"; + TPythonDump() << _editor << " = " + << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()"; - return aMesh._retn(); + SMESH_CATCH( SMESH::throwCorbaException ); + + return aMeshEdVar._retn(); } //============================================================================= @@ -2496,13 +2624,21 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() //============================================================================= SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer() + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_MeshEditor_var aMeshEdVar; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true ); - SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this(); - return aMesh._retn(); + if ( !_previewEditor ) + _previewEditor = new SMESH_MeshEditor_i( this, true ); + aMeshEdVar = _previewEditor->_this(); + + SMESH_CATCH( SMESH::throwCorbaException ); + + return aMeshEdVar._retn(); } //================================================================================ @@ -2566,7 +2702,7 @@ void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOM _impl->SetAutoColor(theAutoColor); TPythonDump pyDump; // not to dump group->SetColor() from below code - pyDump<<_this()<<".SetAutoColor( "< aReservedColors; map::iterator it = _mapGroups.begin(); @@ -2665,25 +2801,23 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, // Perform Export PrepareForWriting(file, overwrite); string aMeshName = "Mesh"; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() ); + SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() ); if ( !aMeshSO->_is_nil() ) { 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::GenericAttribute_wrap anAttr; SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); - SALOMEDS::AttributeExternalFileDef_var aFileName; anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef"); - aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr); + SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr; ASSERT(!aFileName->_is_nil()); aFileName->SetValue(file); - SALOMEDS::AttributeFileType_var aFileType; anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType"); - aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr); + SALOMEDS::AttributeFileType_wrap aFileType = anAttr; ASSERT(!aFileType->_is_nil()); aFileType->SetValue("FICHIERMED"); } @@ -2691,7 +2825,8 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, } // Update Python script // set name of mesh before export - TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')"; + TPythonDump() << _gen_i << ".SetName(" + << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')"; // check names of groups checkGroupNames(); @@ -2708,18 +2843,23 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, void SMESH_Mesh_i::ExportToMEDX (const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion, - CORBA::Boolean overwrite) + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension) throw(SALOME::SALOME_Exception) { - Unexpect aCatch(SALOME_SalomeException); + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); string aMeshName = prepareMeshNameAndGroups(file, overwrite); - TPythonDump() << _this() << ".ExportToMEDX( r'" - << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )"; + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion ); + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'" + << file << "', " << auto_groups << ", " + << theVersion << ", " << overwrite << ", " + << autoDimension << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); } //================================================================================ @@ -2764,7 +2904,8 @@ void SMESH_Mesh_i::ExportSAUV (const char* file, _preMeshInfo->FullLoadFromFile(); string aMeshName = prepareMeshNameAndGroups(file, true); - TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var( _this()) + << ".ExportSAUV( r'" << file << "', " << auto_groups << " )"; _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups); } @@ -2785,7 +2926,7 @@ void SMESH_Mesh_i::ExportDAT (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2808,7 +2949,7 @@ void SMESH_Mesh_i::ExportUNV (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2831,84 +2972,383 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_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_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; - virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const; - virtual SMDS_ElemIteratorPtr elementEntityIterator(SMDSAbs_EntityType type) 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) +void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION version, + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) throw (SALOME::SALOME_Exception) { - Unexpect aCatch(SALOME_SalomeException); + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - PrepareForWriting(file, overwrite); + // check fields + bool have0dField = false; + if ( fields.length() > 0 ) + { + GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh(); + if ( shapeToMesh->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR ); - 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; + for ( size_t i = 0; i < fields.length(); ++i ) + { + if ( fields[i]->GetDataType() == GEOM::FDT_String ) + THROW_SALOME_CORBA_EXCEPTION + ( "Export of string fields is not supported", SALOME::BAD_PARAM); + GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape(); + if ( fieldShape->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR ); + if ( !fieldShape->IsSame( shapeToMesh ) ) + THROW_SALOME_CORBA_EXCEPTION + ( "Field defined not on shape", SALOME::BAD_PARAM); + if ( fields[i]->GetDimension() == 0 ) + have0dField = true; } + if ( geomAssocFields ) + for ( int i = 0; geomAssocFields[i]; ++i ) + switch ( geomAssocFields[i] ) { + case 'v':case 'e':case 'f':case 's': break; + case 'V':case 'E':case 'F':case 'S': break; + default: THROW_SALOME_CORBA_EXCEPTION + ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM); + } } - SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS ); - TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', " - << auto_groups << ", " << version << ", " << overwrite << " )"; -} + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); + + // write mesh + + string aMeshName = "Mesh"; + SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0); + if ( CORBA::is_nil( meshPart ) || + SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) + { + aMeshName = prepareMeshNameAndGroups(file, overwrite); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, + version, 0, autoDimension, have0dField); + meshDS = _impl->GetMeshDS(); + } + else + { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + PrepareForWriting(file, overwrite); + + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart ); + if ( !SO->_is_nil() ) { + CORBA::String_var name = SO->GetName(); + aMeshName = name; + } + } + SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, + version, partDS, autoDimension, have0dField); + meshDS = tmpDSDeleter._obj = partDS; + } + + // write fields + + if ( _impl->HasShapeToMesh() ) + { + DriverMED_W_Field fieldWriter; + fieldWriter.SetFile( file ); + fieldWriter.SetMeshName( aMeshName ); + fieldWriter.AddODOnVertices( have0dField ); + + exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + } + + // dump + GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO; + goList->length( fields.length() ); + for ( size_t i = 0; i < fields.length(); ++i ) + { + GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] ); + goList[i] = gbo; + } + TPythonDump() << _this() << ".ExportPartToMED( " + << meshPart << ", r'" << file << "', " + << auto_groups << ", " << version << ", " << overwrite << ", " + << autoDimension << ", " << goList + << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + +//================================================================================ +/*! + * Write GEOM fields to MED file + */ +//================================================================================ + +void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, + SMESHDS_Mesh* meshDS, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) +{ +#define METH "SMESH_Mesh_i::exportMEDFields() " + + if (( fields.length() < 1 ) && + ( !geomAssocFields || !geomAssocFields[0] )) + return; + + std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 ); + std::vector< int > intVals( meshDS->MaxShapeIndex()+1 ); + std::vector< int > subIdsByDim[ 4 ]; + const double noneDblValue = 0.; + const double noneIntValue = 0; + + for ( size_t iF = 0; iF < fields.length(); ++iF ) + { + // set field data + + int dim = fields[ iF ]->GetDimension(); + SMDSAbs_ElementType elemType; + TopAbs_ShapeEnum shapeType; + switch ( dim ) { + case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break; + case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break; + case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break; + case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break; + default: + continue; // skip fields on whole shape + } + GEOM::field_data_type dataType = fields[ iF ]->GetDataType(); + if ( dataType == GEOM::FDT_String ) + continue; + GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps(); + if ( stepIDs->length() < 1 ) + continue; + GEOM::string_array_var comps = fields[ iF ]->GetComponents(); + if ( comps->length() < 1 ) + continue; + CORBA::String_var name = fields[ iF ]->GetName(); + + if ( !fieldWriter.Set( meshDS, + name.in(), + elemType, + comps->length(), + ( dataType == GEOM::FDT_Int ))) + continue; + + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.SetCompName( iC, comps[ iC ].in() ); + + // find sub-shape IDs + + std::vector< int >& subIds = subIdsByDim[ dim ]; + if ( subIds.empty() ) + for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id ) + if ( meshDS->IndexToShape( id ).ShapeType() == shapeType ) + subIds.push_back( id ); + + // write steps + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + for ( size_t iS = 0; iS < stepIDs->length(); ++iS ) + { + GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]); + if ( step->_is_nil() ) + continue; + + CORBA::Long stamp = step->GetStamp(); + CORBA::Long id = step->GetID(); + fieldWriter.SetDtIt( int( stamp ), int( id )); + + // fill dblVals or intVals + switch ( dataType ) + { + case GEOM::FDT_Double: + { + GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step ); + if ( dblStep->_is_nil() ) continue; + GEOM::ListOfDouble_var vv = dblStep->GetValues(); + if ( vv->length() != subIds.size() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + dblVals[ subIds[ i ]] = vv[ i ]; + break; + } + case GEOM::FDT_Int: + { + GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step ); + if ( intStep->_is_nil() ) continue; + GEOM::ListOfLong_var vv = intStep->GetValues(); + if ( vv->length() != subIds.size() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + intVals[ subIds[ i ]] = (int) vv[ i ]; + break; + } + case GEOM::FDT_Bool: + { + GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step ); + if ( boolStep->_is_nil() ) continue; + GEOM::short_array_var vv = boolStep->GetValues(); + if ( vv->length() != subIds.size() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + intVals[ subIds[ i ]] = (int) vv[ i ]; + break; + } + default: continue; + } + + // pass values to fieldWriter + elemIt = fieldWriter.GetOrderedElems(); + if ( dataType == GEOM::FDT_Double ) + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 || shapeID >= dblVals.size() ) + fieldWriter.AddValue( noneDblValue ); + else + fieldWriter.AddValue( dblVals[ shapeID ]); + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 || shapeID >= intVals.size() ) + fieldWriter.AddValue( noneIntValue ); + else + fieldWriter.AddValue( intVals[ shapeID ]); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on steps + } // loop on fields + + if ( !geomAssocFields || !geomAssocFields[0] ) + return; + + // write geomAssocFields + + std::vector< int > shapeDim( TopAbs_SHAPE + 1 ); + shapeDim[ TopAbs_COMPOUND ] = 3; + shapeDim[ TopAbs_COMPSOLID ] = 3; + shapeDim[ TopAbs_SOLID ] = 3; + shapeDim[ TopAbs_SHELL ] = 2; + shapeDim[ TopAbs_FACE ] = 2; + shapeDim[ TopAbs_WIRE ] = 1; + shapeDim[ TopAbs_EDGE ] = 1; + shapeDim[ TopAbs_VERTEX ] = 0; + shapeDim[ TopAbs_SHAPE ] = 3; + + for ( int iF = 0; geomAssocFields[ iF ]; ++iF ) + { + std::vector< std::string > compNames; + switch ( geomAssocFields[ iF ]) { + case 'v': case 'V': + fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true ); + compNames.push_back( "dim" ); + break; + case 'e': case 'E': + fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true ); + break; + case 'f': case 'F': + fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true ); + break; + case 's': case 'S': + fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true ); + break; + default: continue; + } + compNames.push_back( "id" ); + for ( size_t iC = 0; iC < compNames.size(); ++iC ) + fieldWriter.SetCompName( iC, compNames[ iC ].c_str() ); + + fieldWriter.SetDtIt( -1, -1 ); + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + if ( compNames.size() == 2 ) // _vertices_ + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + { + fieldWriter.AddValue( -1 ); + fieldWriter.AddValue( -1 ); + } + else + { + const TopoDS_Shape& S = meshDS->IndexToShape( shapeID ); + fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]); + fieldWriter.AddValue( shapeID ); + } + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + fieldWriter.AddValue( -1 ); + else + fieldWriter.AddValue( shapeID ); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on geomAssocFields + +#undef METH +} //================================================================================ -/*! - * \brief Export a part of mesh to a DAT file - */ -//================================================================================ +/*! + * \brief Export a part of mesh to a DAT file + */ +//================================================================================ void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart, const char* file) @@ -2923,7 +3363,8 @@ void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportDAT(file,&partDS); - TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )"; } //================================================================================ /*! @@ -2944,7 +3385,8 @@ void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportUNV(file, &partDS); - TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )"; } //================================================================================ /*! @@ -2966,7 +3408,7 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportSTL(file, isascii, &partDS); - TPythonDump() << _this() << ".ExportPartToSTL( " + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( " << meshPart<< ", r'" << file << "', " << isascii << ")"; } @@ -2991,31 +3433,54 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportCGNS(file, &partDS); - TPythonDump() << _this() << ".ExportCGNS( " + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( " << meshPart<< ", r'" << file << "', " << overwrite << ")"; #else THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); #endif } -//============================================================================= +//================================================================================ /*! - * Return implementation of SALOME_MED::MESH interfaces + * \brief Export a part of mesh to a GMF file */ -//============================================================================= +//================================================================================ -SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception) +void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + bool withRequiredGroups) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this); - SALOME_MED::MESH_var aMesh = aMedMesh->_this(); - return aMesh._retn(); + PrepareForWriting(file,/*overwrite=*/true); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportGMF(file, &partDS, withRequiredGroups); + + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( " + << meshPart<< ", r'" + << file << "', " + << withRequiredGroups << ")"; } //============================================================================= +/*! + * Return computation progress [0.,1] + */ +//============================================================================= + +CORBA::Double SMESH_Mesh_i::GetComputeProgress() +{ + SMESH_TRY; + + return _impl->GetComputeProgress(); + + SMESH_CATCH( SMESH::doNothing ); + return 0.; +} CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) { @@ -3092,6 +3557,15 @@ CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception) return _impl->NbTriangles(); } +CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbBiQuadTriangles(); + + return _impl->NbBiQuadTriangles(); +} + CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -3316,7 +3790,7 @@ SMESH::long_array* SMESH_Mesh_i::GetIDs() //============================================================================= SMESH::long_array* SMESH_Mesh_i::GetElementsId() - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -3369,12 +3843,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy int i = 0; - SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator(); - while ( i < nbElements && anIt->more() ) { - const SMDS_MeshElement* anElem = anIt->next(); - if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType ) - aResult[i++] = anElem->GetID(); - } + SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType ); + while ( i < nbElements && anIt->more() ) + aResult[i++] = anIt->next()->GetID(); aResult->length( i ); @@ -3418,10 +3889,17 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem ) throw (SALOME::SALOME_Exception) { + SMESH::ElementType type; + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - return ( SMESH::ElementType )_impl->GetElementType( id, iselem ); + type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem ); + + SMESH_CATCH( SMESH::throwCorbaException ); + + return type; } //============================================================================= @@ -3443,6 +3921,25 @@ SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id ) return ( SMESH::EntityType ) e->GetEntityType(); } +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id ) + throw (SALOME::SALOME_Exception) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id); + if ( !e ) + THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM ); + + return ( SMESH::GeometryType ) e->GetGeomType(); +} + //============================================================================= /*! * Returns ID of elements for given submesh @@ -3451,11 +3948,12 @@ SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id ) SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { + SMESH::long_array_var aResult = new SMESH::long_array(); + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::long_array_var aResult = new SMESH::long_array(); - SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID); if(!SM) return aResult._retn(); @@ -3470,10 +3968,11 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) aResult[i++] = eIt->next()->GetID(); } + SMESH_CATCH( SMESH::throwCorbaException ); + return aResult._retn(); } - //============================================================================= /*! * Returns ID of nodes for given submesh @@ -3481,15 +3980,17 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) * returns only nodes on shapes. */ //============================================================================= + SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all) throw (SALOME::SALOME_Exception) { + SMESH::long_array_var aResult = new SMESH::long_array(); + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::long_array_var aResult = new SMESH::long_array(); - SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID); if(!SM) return aResult._retn(); @@ -3522,6 +4023,8 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) aResult[i++] = *itElem; + SMESH_CATCH( SMESH::throwCorbaException ); + return aResult._retn(); } @@ -3534,6 +4037,9 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { + SMESH::ElementType type; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -3548,7 +4054,12 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID SMDS_ElemIteratorPtr eIt = SDSM->GetElements(); const SMDS_MeshElement* anElem = eIt->next(); - return ( SMESH::ElementType ) anElem->GetType(); + + type = ( SMESH::ElementType ) anElem->GetType(); + + SMESH_CATCH( SMESH::throwCorbaException ); + + return type; } @@ -3694,6 +4205,52 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) return aNodePosition; } +//============================================================================= +/*! + * \brief Return position of an element on shape + */ +//============================================================================= + +SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::ElementPosition anElementPosition; + anElementPosition.shapeID = 0; + anElementPosition.shapeType = GEOM::SHAPE; + + SMESHDS_Mesh* mesh = _impl->GetMeshDS(); + if ( !mesh ) return anElementPosition; + + if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) ) + { + anElementPosition.shapeID = anElem->getshapeId(); + const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() ); + if ( !aSp.IsNull() ) { + switch ( aSp.ShapeType() ) { + case TopAbs_EDGE: + anElementPosition.shapeType = GEOM::EDGE; + break; + case TopAbs_FACE: + anElementPosition.shapeType = GEOM::FACE; + break; + case TopAbs_VERTEX: + anElementPosition.shapeType = GEOM::VERTEX; + break; + case TopAbs_SOLID: + anElementPosition.shapeType = GEOM::SOLID; + break; + case TopAbs_SHELL: + anElementPosition.shapeType = GEOM::SHELL; + break; + default:; + } + } + } + return anElementPosition; +} + //============================================================================= /*! * If given element is node returns IDs of shape from position @@ -3742,7 +4299,6 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id) if(!elem) return -1; - //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); ::SMESH_MeshEditor aMeshEditor(_impl); int index = aMeshEditor.FindShape( elem ); if(index>0) @@ -3941,6 +4497,33 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, return aResult._retn(); } +//======================================================================= +//function : GetElemFaceNodes +//purpose : Returns three components of normal of given mesh face. +//======================================================================= + +SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId, + CORBA::Boolean normalized) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::double_array_var aResult = new SMESH::double_array(); + + if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) + { + gp_XYZ normal; + if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized )) + { + aResult->length( 3 ); + aResult[ 0 ] = normal.X(); + aResult[ 1 ] = normal.Y(); + aResult[ 2 ] = normal.Z(); + } + } + return aResult._retn(); +} + //======================================================================= //function : FindElementByNodes //purpose : Returns an element based on all given nodes. @@ -3959,7 +4542,7 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) if ( !( nn[i] = mesh->FindNode( nodes[i] ))) return elemID; - const SMDS_MeshElement* elem = mesh->FindElement( nn ); + const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false ); if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) || _impl->NbFaces ( ORDER_QUADRATIC ) || _impl->NbVolumes( ORDER_QUADRATIC ))) @@ -4076,6 +4659,96 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) return aResult._retn(); } +//================================================================================ +/*! + * \brief Create a group of elements preventing computation of a sub-shape + */ +//================================================================================ + +SMESH::ListOfGroups* +SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, + const char* theGroupName ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + if ( !theGroupName || strlen( theGroupName) == 0 ) + THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM ); + + SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups; + + // submesh by subshape id + if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1; + if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID )) + { + // compute error + SMESH_ComputeErrorPtr error = sm->GetComputeError(); + if ( error && !error->myBadElements.empty()) + { + // sort bad elements by type + vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ]; + list::iterator elemIt = error->myBadElements.begin(); + list::iterator elemEnd = error->myBadElements.end(); + for ( ; elemIt != elemEnd; ++elemIt ) + { + const SMDS_MeshElement* elem = *elemIt; + if ( !elem ) continue; + + if ( elem->GetID() < 1 ) + { + // elem is a temporary element, make a real element + vector< const SMDS_MeshNode* > nodes; + SMDS_NodeIteratorPtr nIt = elem->nodeIterator(); + while ( nIt->more() && elem ) + { + nodes.push_back( nIt->next() ); + if ( nodes.back()->GetID() < 1 ) + elem = 0; // a temporary element on temporary nodes + } + if ( elem ) + { + ::SMESH_MeshEditor editor( _impl ); + elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() ); + } + } + if ( elem ) + elemsByType[ elem->GetType() ].push_back( elem ); + } + + // how many groups to create? + int nbTypes = 0; + for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i ) + nbTypes += int( !elemsByType[ i ].empty() ); + groups->length( nbTypes ); + + // create groups + for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i ) + { + vector< const SMDS_MeshElement* >& elems = elemsByType[ i ]; + if ( elems.empty() ) continue; + + groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName ); + if ( _gen_i->CanPublishInStudy( groups[ iG ] )) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, mesh, groups[ iG ], + GEOM::GEOM_Object::_nil(), theGroupName); + aSO->_is_nil(); // avoid "unused variable" warning + } + SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]); + if ( !grp_i ) continue; + + if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() )) + for ( size_t iE = 0; iE < elems.size(); ++iE ) + grpDS->SMDSGroup().Add( elems[ iE ]); + } + } + } + + return groups._retn(); +} //============================================================================= /*! @@ -4083,9 +4756,10 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) */ //============================================================================= -void SMESH_Mesh_i::CreateGroupServants() +void SMESH_Mesh_i::CreateGroupServants() { - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + SMESH::SMESH_Mesh_var aMesh = _this(); set addedIDs; ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups(); @@ -4111,22 +4785,19 @@ void SMESH_Mesh_i::CreateGroupServants() aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); } - // To ensure correct mapping of servant and correct reference counting in GenericObj_i - SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl ); - aGroupImpl->Register(); - - SMESH::SMESH_GroupBase_var groupVar = - SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() ); + SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this(); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar ); + aGroupImpl->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( groupVar ); - if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); + if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); } + else { nextId = 0; } // avoid "unused variable" warning in release mode // 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()); + _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName()); } } if ( !addedIDs.empty() ) @@ -4137,7 +4808,7 @@ void SMESH_Mesh_i::CreateGroupServants() { map::iterator it = _mapGroups.find(*id); int i = std::distance( _mapGroups.begin(), it ); - TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]"; + TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]"; } } } @@ -4171,11 +4842,11 @@ SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list& groupIDs) const */ //============================================================================= -SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo() +SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo() { - SALOME_MED::MedFileInfo_var res( _medFileInfo ); + SMESH::MedFileInfo_var res( _medFileInfo ); if ( !res.operator->() ) { - res = new SALOME_MED::MedFileInfo; + res = new SMESH::MedFileInfo; res->fileName = ""; res->fileSize = res->major = res->minor = res->release = -1; } @@ -4194,7 +4865,7 @@ void SMESH_Mesh_i::checkGroupNames() if ( !nbGrp ) return; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( aStudy->_is_nil() ) return; // nothing to do @@ -4210,7 +4881,7 @@ void SMESH_Mesh_i::checkGroupNames() SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ]; if ( !aGrp ) continue; - SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp ); + SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp ); if ( aGrpSO->_is_nil() ) continue; // correct name of the mesh group if necessary @@ -4227,9 +4898,8 @@ void SMESH_Mesh_i::checkGroupNames() //============================================================================= void SMESH_Mesh_i::SetParameters(const char* theParameters) { - // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()), - // CORBA::string_dup(theParameters)); - SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters); + SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(), + theParameters ); } //============================================================================= @@ -4237,10 +4907,10 @@ void SMESH_Mesh_i::SetParameters(const char* theParameters) * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol */ //============================================================================= + char* SMESH_Mesh_i::GetParameters() { - SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen(); - return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this()))); + return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) ); } //============================================================================= @@ -4253,9 +4923,9 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() SMESH::string_array_var aResult = new SMESH::string_array(); SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen(); if(gen) { - char *aParameters = GetParameters(); - SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy(); - if(!aStudy->_is_nil()) { + CORBA::String_var aParameters = GetParameters(); + SALOMEDS::Study_var aStudy = gen->GetCurrentStudy(); + if ( !aStudy->_is_nil()) { SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); if(aSections->length() > 0) { SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1]; @@ -4315,7 +4985,7 @@ bool SMESH_Mesh_i::IsMeshInfoCorrect() //============================================================================= /*! - * \brief Returns statistic of mesh elements + * \brief Returns number of mesh elements per each \a EntityType */ //============================================================================= @@ -4339,7 +5009,33 @@ SMESH::long_array* SMESH_Mesh_i::GetMeshInfo() //============================================================================= /*! - * \brief Collect statistic of mesh elements given by iterator + * \brief Returns number of mesh elements per each \a ElementType + */ +//============================================================================= + +SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType() +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::NB_ELEMENT_TYPES); + for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) + aRes[ i ] = 0; + + const SMDS_MeshInfo* meshInfo = 0; + if ( _preMeshInfo ) + meshInfo = _preMeshInfo; + else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() ) + meshInfo = & meshDS->GetMeshInfo(); + + if (meshInfo) + for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) + aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i); + + return aRes._retn(); +} + +//============================================================================= +/* + * Collect statistic of mesh elements given by iterator */ //============================================================================= @@ -4352,12 +5048,240 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, } //============================================================================= -/*! - * \brief mapping of mesh dimension into shape type +namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj, + * SMESH::ElementType type) */ +{ + using namespace SMESH::Controls; + //----------------------------------------------------------------------------- + struct PredicateIterator : public SMDS_ElemIterator + { + SMDS_ElemIteratorPtr _elemIter; + PredicatePtr _predicate; + const SMDS_MeshElement* _elem; + + PredicateIterator( SMDS_ElemIteratorPtr iterator, + PredicatePtr predicate): + _elemIter(iterator), _predicate(predicate) + { + next(); + } + virtual bool more() + { + return _elem; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _elem; + _elem = 0; + while ( _elemIter->more() && !_elem ) + { + _elem = _elemIter->next(); + if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() ))) + _elem = 0; + } + return res; + } + }; + + //----------------------------------------------------------------------------- + struct IDSourceIterator : public SMDS_ElemIterator + { + const CORBA::Long* _idPtr; + const CORBA::Long* _idEndPtr; + SMESH::long_array_var _idArray; + const SMDS_Mesh* _mesh; + const SMDSAbs_ElementType _type; + const SMDS_MeshElement* _elem; + + IDSourceIterator( const SMDS_Mesh* mesh, + const CORBA::Long* ids, + const int nbIds, + SMDSAbs_ElementType type): + _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 ) + { + if ( _idPtr && nbIds && _mesh ) + next(); + } + IDSourceIterator( const SMDS_Mesh* mesh, + SMESH::long_array* idArray, + SMDSAbs_ElementType type): + _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 ) + { + if ( idArray && _mesh ) + { + _idPtr = &_idArray[0]; + _idEndPtr = _idPtr + _idArray->length(); + next(); + } + } + virtual bool more() + { + return _elem; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _elem; + _elem = 0; + while ( _idPtr < _idEndPtr && !_elem ) + { + if ( _type == SMDSAbs_Node ) + { + _elem = _mesh->FindNode( *_idPtr++ ); + } + else if ((_elem = _mesh->FindElement( *_idPtr++ )) && + _elem->GetType() != _type ) + { + _elem = 0; + } + } + return res; + } + }; + //----------------------------------------------------------------------------- + + struct NodeOfElemIterator : public SMDS_ElemIterator + { + TColStd_MapOfInteger _checkedNodeIDs; + SMDS_ElemIteratorPtr _elemIter; + SMDS_ElemIteratorPtr _nodeIter; + const SMDS_MeshElement* _node; + + NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 ) + { + if ( _elemIter && _elemIter->more() ) + { + _nodeIter = _elemIter->next()->nodesIterator(); + next(); + } + } + virtual bool more() + { + return _node; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _node; + _node = 0; + while (( _elemIter->more() || _nodeIter->more() ) && !_node ) + { + if ( _nodeIter->more() ) + { + _node = _nodeIter->next(); + if ( !_checkedNodeIDs.Add( _node->GetID() )) + _node = 0; + } + else + { + _nodeIter = _elemIter->next()->nodesIterator(); + } + } + return res; + } + }; +} + +//============================================================================= +/* + * Return iterator on elements of given type in given object */ //============================================================================= -static TopAbs_ShapeEnum shapeTypeByDim(const int theDim) +SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject, + SMESH::ElementType theType) +{ + SMDS_ElemIteratorPtr elemIt; + bool typeOK = false; + SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType ); + + SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( meshVar ); + if ( !mesh_i ) return elemIt; + SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS(); + + if ( SMESH::DownCast( theObject )) + { + elemIt = meshDS->elementsIterator( elemType ); + typeOK = true; + } + else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast( theObject )) + { + SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() ); + if ( sm ) + { + elemIt = sm->GetElements(); + if ( elemType != SMDSAbs_Node ) + { + typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType ); + elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr(); + } + } + } + else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( theObject )) + { + SMESHDS_GroupBase* groupDS = group_i->GetGroupDS(); + if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node )) + { + elemIt = groupDS->GetElements(); + typeOK = ( groupDS->GetType() == elemType ); + } + } + else if ( SMESH::Filter_i* filter_i = SMESH::DownCast( theObject )) + { + if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node ) + { + SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i(); + if ( pred_i && pred_i->GetPredicate() ) + { + SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() ); + SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType ); + elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() )); + typeOK = ( filterType == elemType ); + } + } + } + else + { + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE ); + if ( isNodes && elemType != SMDSAbs_Node ) + return elemIt; + if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject )) + { + int nbIds; + if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds )) + elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType )); + } + else + { + SMESH::long_array_var ids = theObject->GetIDs(); + elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType )); + } + typeOK = ( isNodes == ( elemType == SMDSAbs_Node )); + } + + if ( elemIt && elemIt->more() && !typeOK ) + { + if ( elemType == SMDSAbs_Node ) + { + elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt )); + } + else + { + elemIt = SMDS_ElemIteratorPtr(); + } + } + return elemIt; +} + +//============================================================================= +namespace // Finding concurrent hypotheses +//============================================================================= +{ + +/*! + * \brief mapping of mesh dimension into shape type + */ +TopAbs_ShapeEnum shapeTypeByDim(const int theDim) { TopAbs_ShapeEnum aType = TopAbs_SOLID; switch ( theDim ) { @@ -4370,7 +5294,7 @@ static TopAbs_ShapeEnum shapeTypeByDim(const int theDim) return aType; } -//============================================================================= +//----------------------------------------------------------------------------- /*! * \brief Internal structure used to find concurent submeshes * @@ -4379,8 +5303,6 @@ static TopAbs_ShapeEnum shapeTypeByDim(const int theDim) * with another submesh. In other words, it is dimension of a hypothesis assigned * to submesh. */ -//============================================================================= - class SMESH_DimHyp { public: @@ -4389,23 +5311,30 @@ class SMESH_DimHyp int _ownDim; //!< dimension of shape of _subMesh (>=_dim) TopTools_MapOfShape _shapeMap; SMESH_subMesh* _subMesh; - list _hypothesises; //!< algo is first, then its parameters + list _hypotheses; //!< algo is first, then its parameters + + //----------------------------------------------------------------------------- + // Return the algorithm + const SMESH_Algo* GetAlgo() const + { return _hypotheses.empty() ? 0 : dynamic_cast( _hypotheses.front() ); } + //----------------------------------------------------------------------------- //! Constructors - SMESH_DimHyp(const SMESH_subMesh* theSubMesh, - const int theDim, - const TopoDS_Shape& theShape) + SMESH_DimHyp(const SMESH_subMesh* theSubMesh, + const int theDim, + const TopoDS_Shape& theShape) { _subMesh = (SMESH_subMesh*)theSubMesh; SetShape( theDim, theShape ); } + //----------------------------------------------------------------------------- //! set shape void SetShape(const int theDim, const TopoDS_Shape& theShape) { _dim = theDim; - _ownDim = (int)SMESH_Gen::GetShapeDim(theShape); + _ownDim = SMESH_Gen::GetShapeDim(theShape); if (_dim >= _ownDim) _shapeMap.Add( theShape ); else { @@ -4415,6 +5344,7 @@ class SMESH_DimHyp } } + //----------------------------------------------------------------------------- //! Check sharing of sub-shapes static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck, const TopTools_MapOfShape& theToFind, @@ -4435,11 +5365,13 @@ class SMESH_DimHyp return isShared; } + //----------------------------------------------------------------------------- //! check algorithms static bool checkAlgo(const SMESHDS_Hypothesis* theA1, const SMESHDS_Hypothesis* theA2) { - if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO || + if ( !theA1 || !theA2 || + theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO || theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ) return false; // one of the hypothesis is not algorithm // check algorithm names (should be equal) @@ -4447,6 +5379,7 @@ class SMESH_DimHyp } + //----------------------------------------------------------------------------- //! Check if sub-shape hypotheses are concurrent bool IsConcurrent(const SMESH_DimHyp* theOther) const { @@ -4456,8 +5389,10 @@ class SMESH_DimHyp // if ( == && // any of the two submeshes is not on COMPOUND shape ) // -> no concurrency - bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh()); - bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh()); + bool meIsCompound = (_subMesh->GetSubMeshDS() && + _subMesh->GetSubMeshDS()->IsComplexSubmesh()); + bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && + theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh()); if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound)) return false; @@ -4469,65 +5404,102 @@ class SMESH_DimHyp return false; // check algorithms to be same - if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() )) - return true; // different algorithms - + if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() )) + return true; // different algorithms -> concurrency ! + // check hypothesises for concurrence (skip first as algorithm) int nbSame = 0; - // pointers should be same, becase it is referenes from mesh hypothesis partition - list ::const_iterator hypIt = _hypothesises.begin(); - list ::const_iterator otheEndIt = theOther->_hypothesises.end(); - for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ ) - if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt ) + // pointers should be same, because it is referened from mesh hypothesis partition + list ::const_iterator hypIt = _hypotheses.begin(); + list ::const_iterator otheEndIt = theOther->_hypotheses.end(); + for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ ) + if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt ) nbSame++; // the submeshes are concurrent if their algorithms has different parameters - return nbSame != theOther->_hypothesises.size() - 1; + return nbSame != theOther->_hypotheses.size() - 1; + } + + // Return true if algorithm of this SMESH_DimHyp is used if no + // sub-mesh order is imposed by the user + bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const + { + // NeedDiscreteBoundary() algo has a higher priority + if ( this ->GetAlgo()->NeedDiscreteBoundary() != + theOther->GetAlgo()->NeedDiscreteBoundary() ) + return !this->GetAlgo()->NeedDiscreteBoundary(); + + return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() ); } }; // end of SMESH_DimHyp +//----------------------------------------------------------------------------- + +typedef list TDimHypList; -typedef list TDimHypList; +//----------------------------------------------------------------------------- -static void addDimHypInstance(const int theDim, - const TopoDS_Shape& theShape, - const SMESH_Algo* theAlgo, - const SMESH_subMesh* theSubMesh, - const list & theHypList, - TDimHypList* theDimHypListArr ) +void addDimHypInstance(const int theDim, + const TopoDS_Shape& theShape, + const SMESH_Algo* theAlgo, + const SMESH_subMesh* theSubMesh, + const list & theHypList, + TDimHypList* theDimHypListArr ) { TDimHypList& listOfdimHyp = theDimHypListArr[theDim]; if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) { SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape ); + dimHyp->_hypotheses.push_front(theAlgo); listOfdimHyp.push_back( dimHyp ); } - SMESH_DimHyp* dimHyp = listOfdimHyp.back(); - dimHyp->_hypothesises.push_front(theAlgo); - list ::const_iterator hypIt = theHypList.begin(); - for( ; hypIt != theHypList.end(); hypIt++ ) - dimHyp->_hypothesises.push_back( *hypIt ); + SMESH_DimHyp* dimHyp = const_cast( listOfdimHyp.back() ); + dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(), + theHypList.begin(), theHypList.end() ); } -static void findConcurrents(const SMESH_DimHyp* theDimHyp, - const TDimHypList& theListOfDimHyp, - TListOfInt& theListOfConcurr ) +//----------------------------------------------------------------------------- +void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp, + TDimHypList& theListOfConcurr) +{ + if ( theListOfConcurr.empty() ) + { + theListOfConcurr.push_back( theDimHyp ); + } + else + { + TDimHypList::iterator hypIt = theListOfConcurr.begin(); + while ( hypIt != theListOfConcurr.end() && + !theDimHyp->IsHigherPriorityThan( *hypIt )) + ++hypIt; + theListOfConcurr.insert( hypIt, theDimHyp ); + } +} + +//----------------------------------------------------------------------------- +void findConcurrents(const SMESH_DimHyp* theDimHyp, + const TDimHypList& theListOfDimHyp, + TDimHypList& theListOfConcurrHyp, + set& theSetOfConcurrId ) { TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin(); - for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) { + for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) + { const SMESH_DimHyp* curDimHyp = *rIt; if ( curDimHyp == theDimHyp ) break; // meet own dimHyp pointer in same dimension - else if ( theDimHyp->IsConcurrent( curDimHyp ) ) - if ( find( theListOfConcurr.begin(), - theListOfConcurr.end(), - curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() ) - theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() ); + + if ( theDimHyp->IsConcurrent( curDimHyp ) && + theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second ) + { + addInOrderOfPriority( curDimHyp, theListOfConcurrHyp ); + } } } -static void unionLists(TListOfInt& theListOfId, - TListOfListOfInt& theListOfListOfId, - const int theIndx ) +//----------------------------------------------------------------------------- +void unionLists(TListOfInt& theListOfId, + TListOfListOfInt& theListOfListOfId, + const int theIndx ) { TListOfListOfInt::iterator it = theListOfListOfId.begin(); for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) { @@ -4549,9 +5521,10 @@ static void unionLists(TListOfInt& theListOfId, otherListOfId.clear(); } } +//----------------------------------------------------------------------------- //! free memory allocated for dimension-hypothesis objects -static void removeDimHyps( TDimHypList* theArrOfList ) +void removeDimHyps( TDimHypList* theArrOfList ) { for (int i = 0; i < 4; i++ ) { TDimHypList& listOfdimHyp = theArrOfList[i]; @@ -4561,6 +5534,57 @@ static void removeDimHyps( TDimHypList* theArrOfList ) } } +//----------------------------------------------------------------------------- +/*! + * \brief find common submeshes with given submesh + * \param theSubMeshList list of already collected submesh to check + * \param theSubMesh given submesh to intersect with other + * \param theCommonSubMeshes collected common submeshes + */ +void findCommonSubMesh (list& theSubMeshList, + const SMESH_subMesh* theSubMesh, + set& theCommon ) +{ + if ( !theSubMesh ) + return; + list::const_iterator it = theSubMeshList.begin(); + for ( ; it != theSubMeshList.end(); it++ ) + theSubMesh->FindIntersection( *it, theCommon ); + theSubMeshList.push_back( theSubMesh ); + //theCommon.insert( theSubMesh ); +} + +//----------------------------------------------------------------------------- +bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists ) +{ + TListOfListOfInt::const_iterator listsIt = smLists.begin(); + for ( ; listsIt != smLists.end(); ++listsIt ) + { + const TListOfInt& smIDs = *listsIt; + if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() ) + return true; + } + return false; +} + +} // namespace + +//============================================================================= +/*! + * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh + */ +//============================================================================= + +CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID) +{ + TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order + if ( isSubMeshInList( submeshID, anOrder )) + return false; + + TListOfListOfInt allConurrent = findConcurrentSubMeshes(); + return isSubMeshInList( submeshID, allConurrent ); +} + //============================================================================= /*! * \brief Return submesh objects list in meshing order @@ -4574,20 +5598,43 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); if ( !aMeshDS ) return aResult._retn(); - - ::SMESH_Mesh& mesh = GetImpl(); - TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order? - if ( !anOrder.size() ) { - // collect submeshes detecting concurrent algorithms and hypothesises + TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order + TListOfListOfInt allConurrent = findConcurrentSubMeshes(); + anOrder.splice( anOrder.end(), allConurrent ); + + int listIndx = 0; + TListOfListOfInt::iterator listIt = anOrder.begin(); + for(; listIt != anOrder.end(); listIt++, listIndx++ ) + unionLists( *listIt, anOrder, listIndx + 1 ); + + // convert submesh ids into interface instances + // and dump command into python + convertMeshOrder( anOrder, aResult, false ); + + return aResult._retn(); +} + +//============================================================================= +/*! + * \brief Finds concurrent sub-meshes + */ +//============================================================================= + +TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() +{ + TListOfListOfInt anOrder; + ::SMESH_Mesh& mesh = GetImpl(); + { + // collect submeshes and detect concurrent algorithms and hypothesises TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension - + map::iterator i_sm = _mapSubMesh.begin(); for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) { ::SMESH_subMesh* sm = (*i_sm).second; // shape of submesh const TopoDS_Shape& aSubMeshShape = sm->GetSubShape(); - + // list of assigned hypothesises const list & hypList = mesh.GetHypothesisList(aSubMeshShape); // Find out dimensions where the submesh can be concurrent. @@ -4606,7 +5653,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() ); } if (!anAlgo) - continue; // no assigned algorithm to current submesh + continue; // no algorithm assigned to a current submesh int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp) // the submesh can concurrent at (or lower dims if !anAlgo->NeedDiscreteBoundary()) @@ -4619,20 +5666,25 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() // iterate on created dimension-hypotheses and check for concurrents for ( int i = 0; i < 4; i++ ) { - const list& listOfDimHyp = dimHypListArr[i]; + const TDimHypList& listOfDimHyp = dimHypListArr[i]; // check for concurrents in own and other dimensions (step-by-step) TDimHypList::const_iterator dhIt = listOfDimHyp.begin(); for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) { const SMESH_DimHyp* dimHyp = *dhIt; - TListOfInt listOfConcurr; + TDimHypList listOfConcurr; + set setOfConcurrIds; // looking for concurrents and collect into own list for ( int j = i; j < 4; j++ ) - findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr ); + findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds ); // check if any concurrents found if ( listOfConcurr.size() > 0 ) { // add own submesh to list of concurrent - listOfConcurr.push_front( dimHyp->_subMesh->GetId() ); - anOrder.push_back( listOfConcurr ); + addInOrderOfPriority( dimHyp, listOfConcurr ); + list listOfConcurrIds; + TDimHypList::iterator hypIt = listOfConcurr.begin(); + for ( ; hypIt != listOfConcurr.end(); ++hypIt ) + listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() ); + anOrder.push_back( listOfConcurrIds ); } } } @@ -4648,33 +5700,8 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() for(; listIt != anOrder.end(); listIt++, listIndx++ ) unionLists( *listIt, anOrder, listIndx + 1 ); } - // convert submesh ids into interface instances - // and dump command into python - convertMeshOrder( anOrder, aResult, false ); - - return aResult._retn(); -} -//============================================================================= -/*! - * \brief find common submeshes with given submesh - * \param theSubMeshList list of already collected submesh to check - * \param theSubMesh given submesh to intersect with other - * \param theCommonSubMeshes collected common submeshes - */ -//============================================================================= - -static void findCommonSubMesh (list& theSubMeshList, - const SMESH_subMesh* theSubMesh, - set& theCommon ) -{ - if ( !theSubMesh ) - return; - list::const_iterator it = theSubMeshList.begin(); - for ( ; it != theSubMeshList.end(); it++ ) - theSubMesh->FindIntersection( *it, theCommon ); - theSubMeshList.push_back( theSubMesh ); - //theCommon.insert( theSubMesh ); + return anOrder; } //============================================================================= @@ -4693,7 +5720,7 @@ static void findCommonSubMesh (list& theSubMeshList, ::SMESH_Mesh& mesh = GetImpl(); TPythonDump aPythonDump; // prevent dump of called methods - aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ "; + aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ "; TListOfListOfInt subMeshOrder; for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ ) @@ -4763,7 +5790,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array(); aResSubSet->length(aSubOrder.size()); TListOfInt::const_iterator subIt = aSubOrder.begin(); - for( int j = 0; subIt != aSubOrder.end(); subIt++ ) { + int j; + for( j = 0; subIt != aSubOrder.end(); subIt++ ) { if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() ) continue; SMESH::SMESH_subMesh_var subMesh = @@ -4777,7 +5805,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, } if ( theIsDump ) aPythonDump << " ]"; - theResOrder[ listIndx++ ] = aResSubSet; + if ( j > 1 ) + theResOrder[ listIndx++ ] = aResSubSet; } // correct number of lists theResOrder.length( listIndx ); @@ -4785,7 +5814,7 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, if ( theIsDump ) { // finilise python dump aPythonDump << " ]"; - aPythonDump << " = " << _this() << ".GetMeshOrder()"; + aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()"; } } @@ -4845,6 +5874,27 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): } } // ------------------------------------------------------------------------------------- +SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart): + SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0) +{ + TMeshInfo tmpInfo; + list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin(); + for ( ; partIt != meshPart.end(); ++partIt ) + if ( const SMDS_MeshElement * e = *partIt ) + 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; +} +// ------------------------------------------------------------------------------------- SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const { if ( _meshDS ) return _meshDS->elementGeomIterator( geomType ); @@ -4917,3 +5967,5 @@ _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDS // END Implementation of SMESH_MeshPartDS // //================================================================================ + +