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=0f827b05463cfc1c02c6ecedb80ffc15551c134c;hp=0f4dd5407fb284706aeb2d1b18a7616786f38c44;hb=e85e13ee2a8e2484050471ff8e4dea298abe481a;hpb=4a3d652a69426daf21bfab3bf950e03665660e2a diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 0f4dd5407..0f827b054 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2020 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 @@ -176,7 +176,7 @@ SMESH_Mesh_i::~SMESH_Mesh_i() /*! * SetShape * - * Associates mesh with and puts a reference + * Associate mesh with and put a reference * to into the current study; * the previous shape is substituted by the new one. */ @@ -201,7 +201,7 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject ) //================================================================================ /*! - * \brief return true if mesh has a shape to build a shape on + * \brief Return true if mesh has a shape to build a shape on */ //================================================================================ @@ -219,10 +219,11 @@ CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh() return res; } -//======================================================================= -//function : GetShapeToMesh -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Return the shape to mesh + */ +//================================================================================ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() throw (SALOME::SALOME_Exception) @@ -256,47 +257,6 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() return aShapeObj._retn(); } -//================================================================================ -/*! -* \brief Replaces a shape in the mesh -*/ -//================================================================================ -void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom) - throw (SALOME::SALOME_Exception) -{ - TopoDS_Shape S = _impl->GetShapeToMesh(); - GEOM_Client* geomClient = _gen_i->GetShapeReader(); - TCollection_AsciiString aIOR; - if (geomClient->Find(S, aIOR)) { - geomClient->RemoveShapeFromBuffer(aIOR); - } - - // update the reference to theNewGeom (needed for correct execution of a dumped python script) - SMESH::SMESH_Mesh_var me = _this(); - SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me ); - CORBA::String_var entry = theNewGeom->GetStudyEntry(); - if ( !aSO->_is_nil() ) - { - SALOMEDS::SObject_wrap aShapeRefSO; - if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() )) - { - SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry ); - SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); - builder->Addreference( aShapeRefSO, aShapeSO ); - } - } - - // re-assign global hypotheses to the new shape - _mainShapeTick = -1; - CheckGeomModif( true ); - - TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject(" - << me <<".GetMesh()), " << entry.in() << ")"; - - TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )"; - -} - //================================================================================ /*! * \brief Return false if the mesh is not yet fully loaded from the study file @@ -428,7 +388,7 @@ static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr /*! * ImportMEDFile * - * Imports mesh data from MED file + * Import mesh data from MED file */ //============================================================================= @@ -466,7 +426,7 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) //================================================================================ /*! - * \brief Imports mesh data from the CGNS file + * \brief Import mesh data from the CGNS file */ //================================================================================ @@ -518,6 +478,7 @@ char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits) * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) */ //================================================================================ + SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend() { SMESH::long_array_var aResult = new SMESH::long_array(); @@ -533,7 +494,7 @@ SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend() /*! * ImportUNVFile * - * Imports mesh data from MED file + * Import mesh data from MED file */ //============================================================================= @@ -563,9 +524,10 @@ int SMESH_Mesh_i::ImportUNVFile( const char* theFileName ) /*! * ImportSTLFile * - * Imports mesh data from STL file + * Import mesh data from STL file */ //============================================================================= + int SMESH_Mesh_i::ImportSTLFile( const char* theFileName ) throw ( SALOME::SALOME_Exception ) { @@ -606,7 +568,7 @@ namespace //================================================================================ /*! - * \brief Imports data from a GMF file and returns an error description + * \brief Import data from a GMF file and return an error description */ //================================================================================ @@ -640,7 +602,7 @@ SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName, //============================================================================= /*! - * + * \brief Convert SMESH_Hypothesis::Hypothesis_Status into SMESH::Hypothesis_Status */ //============================================================================= @@ -674,7 +636,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus /*! * AddHypothesis * - * calls internal addHypothesis() and then adds a reference to under + * Call internal addHypothesis() and then add a reference to under * the SObject actually having a reference to . * NB: For this method to work, it is necessary to add a reference to sub-shape first. */ @@ -701,8 +663,8 @@ SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape, { _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp ); - int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements(); - if ( newNbMeshEnt != prevNbMeshEnt ) + //int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements(); + if ( prevNbMeshEnt > 0 /*newNbMeshEnt != prevNbMeshEnt*/ ) _gen_i->UpdateIcons( mesh ); } if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status ); @@ -714,11 +676,11 @@ SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape, return ConvertHypothesisStatus(status); } -//============================================================================= +//================================================================================ /*! - * + * \brief Create a sub-mesh and add a hypothesis to it */ -//============================================================================= +//================================================================================ SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape, @@ -769,13 +731,13 @@ SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape, return status; } -//============================================================================= +//================================================================================ /*! - * + * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape */ -//============================================================================= +//================================================================================ -SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape, +SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape, SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception) { @@ -804,7 +766,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS //============================================================================= /*! - * + * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape */ //============================================================================= @@ -848,11 +810,11 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape, return status; } -//============================================================================= +//================================================================================ /*! - * + * \brief Return hypotheses assigned to a given sub-shape */ -//============================================================================= +//================================================================================ SMESH::ListOfHypothesis * SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape) @@ -890,6 +852,12 @@ throw(SALOME::SALOME_Exception) return aList._retn(); } +//================================================================================ +/*! + * \brief Return sub-meshes + */ +//================================================================================ + SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -926,11 +894,11 @@ SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Excepti return aList._retn(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Create and return a sub-mesh on the given sub-shape */ -//============================================================================= +//================================================================================ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape, const char* theName ) @@ -947,13 +915,15 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap //Get or Create the SMESH_subMesh object implementation - int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); - - if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape )) + TopoDS_Iterator it( myLocSubShape ); + int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); + bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape )); + if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND ) + isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() ); + if ( !isValidSub ) { - TopoDS_Iterator it( myLocSubShape ); if ( it.More() ) - THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM); + THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM); } subMesh = getSubMesh( subMeshId ); @@ -977,11 +947,11 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap return subMesh._retn(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Remove a sub-mesh */ -//============================================================================= +//================================================================================ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) throw (SALOME::SALOME_Exception) @@ -1020,11 +990,11 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) SMESH_CATCH( SMESH::throwCorbaException ); } -//============================================================================= +//================================================================================ /*! - * + * \brief Create a standalone group */ -//============================================================================= +//================================================================================ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType, const char* theName ) @@ -1050,11 +1020,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType return aNewGroup._retn(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Create a group based on the given geometry */ -//============================================================================= +//================================================================================ + SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, const char* theName, @@ -1134,11 +1105,11 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, return aNewGroup._retn(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Remove a group */ -//============================================================================= +//================================================================================ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception) @@ -1478,6 +1449,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr \return pointer on the group */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, const char* theName ) @@ -1627,6 +1599,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr \return pointer on the group */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, const SMESH::ListOfGroups& theToolGroups, @@ -2066,69 +2039,236 @@ void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj) } } +//================================================================================ +/*! +* \brief Replace a shape in the mesh upon Break Link +*/ +//================================================================================ + +void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom) + throw (SALOME::SALOME_Exception) +{ + // check if geometry changed + bool geomChanged = true; + GEOM::GEOM_Object_var oldGeom = GetShapeToMesh(); + if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() ) + geomChanged = ( //oldGeom->_is_equivalent( theNewGeom ) || + oldGeom->GetTick() < theNewGeom->GetTick() ); + + TopoDS_Shape S = _impl->GetShapeToMesh(); + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + TCollection_AsciiString aIOR; + CORBA::String_var ior; + if ( geomClient->Find( S, aIOR )) + geomClient->RemoveShapeFromBuffer( aIOR ); + + // clear buffer also for sub-groups + const std::set& groups = _impl->GetMeshDS()->GetGroups(); + std::set::const_iterator g = groups.begin(); + for (; g != groups.end(); ++g) + if (const SMESHDS_GroupOnGeom* group = dynamic_cast(*g)) + { + const TopoDS_Shape& s = group->GetShape(); + if ( geomClient->Find( s, aIOR )) + geomClient->RemoveShapeFromBuffer( aIOR ); + } + + typedef struct { + int shapeID, fromID, toID; // indices of elements of a sub-mesh + } TRange; + std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes + std::vector< SMDS_PositionPtr > positions; // node positions + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); + if ( !geomChanged ) + { + // store positions of elements on geometry + Load(); + if ( meshDS->MaxNodeID() > meshDS->NbNodes() || + meshDS->MaxElementID() > meshDS->NbElements() ) + { + meshDS->Modified(); + meshDS->CompactMesh(); + } + positions.resize( meshDS->NbNodes() + 1 ); + for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); ) + { + const SMDS_MeshNode* n = nodeIt->next(); + positions[ n->GetID() ] = n->GetPosition(); + } + + // remove elements from sub-meshes to avoid their removal at hypotheses addition + for ( int isNode = 0; isNode < 2; ++isNode ) + { + std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges; + ranges.reserve( meshDS->MaxShapeIndex() + 10 ); + ranges.push_back( TRange{ 0,0,0 }); + SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All ); + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int elemID = e->GetID(); + const int shapeID = e->GetShapeID(); + TRange & lastRange = ranges.back(); + if ( lastRange.shapeID != shapeID || + lastRange.toID != elemID ) + ranges.push_back( TRange{ shapeID, elemID, elemID + 1 }); + else + lastRange.toID = elemID + 1; + + if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID )) + { + if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e )); + else sm->RemoveElement( e ); + } + } + } + } + + + // update the reference to theNewGeom (needed for correct execution of a dumped python script) + SMESH::SMESH_Mesh_var me = _this(); + SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me ); + CORBA::String_var entry = theNewGeom->GetStudyEntry(); + if ( !aSO->_is_nil() ) + { + SALOMEDS::SObject_wrap aShapeRefSO; + if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() )) + { + SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry ); + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); + builder->Addreference( aShapeRefSO, aShapeSO ); + } + } + + // re-assign global hypotheses to the new shape + _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick(); + CheckGeomModif( true ); + + if ( !geomChanged ) + { + // restore positions of elements on geometry + for ( int isNode = 0; isNode < 2; ++isNode ) + { + std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges; + for ( size_t i = 1; i < ranges.size(); ++i ) + { + int elemID = ranges[ i ].fromID; + int toID = ranges[ i ].toID; + SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID ); + if ( isNode ) + for ( ; elemID < toID; ++elemID ) + smDS->AddNode( meshDS->FindNode( elemID )); + else + for ( ; elemID < toID; ++elemID ) + smDS->AddElement( meshDS->FindElement( elemID )); + + if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID )) + sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + } + } + for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID ) + if ( positions[ nodeID ]) + if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID ))) + n->SetPosition( positions[ nodeID ], n->GetShapeID() ); + + // restore icons + _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() )); + } + + TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject(" + << me <<".GetMesh()), " << entry.in() << ")"; + + TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )"; + +} + //================================================================================ /*! * \brief Return new group contents if it has been changed and update group data */ //================================================================================ + enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED }; TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how ) { TopoDS_Shape newShape; + SALOMEDS::SObject_wrap groupSO; if ( how == IS_BREAK_LINK ) { SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject ); - SALOMEDS::SObject_wrap geomRefSO, geomSO; + SALOMEDS::SObject_wrap geomRefSO; if ( !meshSO->_is_nil() && - meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) && - geomRefSO->ReferencedObject( geomSO.inout() )) + meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() )) { - CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO ); - GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj ); - newShape = _gen_i->GeomObjectToShape( geom ); - CORBA::String_var entry = geom->GetStudyEntry(); - groupData._groupEntry = entry.in(); + geomRefSO->ReferencedObject( groupSO.inout() ); } } else { // get geom group - SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() ); - if ( !groupSO->_is_nil() ) + groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() ); + } + + if ( groupSO->_is_nil() ) + return newShape; + + CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO ); + GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj ); + if ( geomGroup->_is_nil() ) + return newShape; + + // get indices of group items + set curIndices; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup ); + GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations(); + GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); + for ( CORBA::ULong i = 0; i < ids->length(); ++i ) + curIndices.insert( ids[i] ); + + bool sameIndices = ( groupData._indices == curIndices ); + if ( how == ONLY_IF_CHANGED && sameIndices ) + return newShape; // group not changed + + // update data + CORBA::String_var entry = geomGroup->GetStudyEntry(); + groupData._groupEntry = entry.in(); + groupData._indices = curIndices; + + newShape = _gen_i->GeomObjectToShape( geomGroup ); + + // check if newShape is up-to-date + if ( !newShape.IsNull() && ids->length() > 0 ) + { + bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape ); + if ( !toUpdate ) + { + TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup ))); + for ( ; exp.More() && !toUpdate; exp.Next() ) + { + int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() ); + toUpdate = ( curIndices.erase( ind ) == 0 ); + } + if ( !curIndices.empty() ) + toUpdate = true; + } + if ( toUpdate ) { - CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO ); - if ( CORBA::is_nil( groupObj )) return newShape; - GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj ); - - // get indices of group items - set curIndices; - GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup ); - GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations(); - GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); - for ( CORBA::ULong i = 0; i < ids->length(); ++i ) - curIndices.insert( ids[i] ); - - if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices ) - return newShape; // group not changed - - // update data - groupData._indices = curIndices; - - GEOM_Client* geomClient = _gen_i->GetShapeReader(); - if ( !geomClient ) return newShape; + GEOM_Client* geomClient = _gen_i->GetShapeReader(); CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup ); geomClient->RemoveShapeFromBuffer( groupIOR.in() ); newShape = _gen_i->GeomObjectToShape( geomGroup ); } } - if ( newShape.IsNull() ) { + else + { // geom group becomes empty - return empty compound TopoDS_Compound compound; BRep_Builder().MakeCompound(compound); newShape = compound; } + return newShape; } @@ -2221,7 +2361,7 @@ namespace */ //============================================================================= -void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) +void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink ) { SMESH::SMESH_Mesh_var me = _this(); GEOM::GEOM_Object_var mainGO = GetShapeToMesh(); @@ -2279,17 +2419,18 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) // Update after group modification - if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified - mainGO->GetTick() == _mainShapeTick ) - { - int nb = NbNodes() + NbElements(); - CheckGeomGroupModif(); - if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change - _gen_i->UpdateIcons( me ); - return; - } + const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick ); + if ( !theIsBreakLink ) + if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified + { + int nb = NbNodes() + NbElements(); + CheckGeomGroupModif(); + if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change + _gen_i->UpdateIcons( me ); + return; + } - // Update after shape modification + // Update after shape modification or breakLink w/o geometry change GEOM_Client* geomClient = _gen_i->GetShapeReader(); if ( !geomClient ) return; @@ -2298,8 +2439,15 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) CORBA::String_var geomComponentType = geomGen->ComponentDataType(); bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 ); - CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); - geomClient->RemoveShapeFromBuffer( ior.in() ); + SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); + + TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO ); + if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated + { + CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + newShape = _gen_i->GeomObjectToShape( mainGO ); + } // Update data taking into account that if topology doesn't change // all sub-shapes change but IDs of sub-shapes remain (except for geom groups) @@ -2307,18 +2455,14 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) if ( _preMeshInfo ) _preMeshInfo->ForgetAllData(); - - if ( isBreakLink || !isShaper ) + if ( geomChanged || !isShaper ) _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 + // store data of groups on geometry including new TopoDS_Shape's std::vector< TGroupOnGeomData > groupsData; const std::set& groups = meshDS->GetGroups(); groupsData.reserve( groups.size() ); @@ -2339,7 +2483,10 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) GEOM::GEOM_Object_var geom; if ( !gog->_is_nil() ) { - if ( isBreakLink ) + if ( !theIsBreakLink ) + geom = gog->GetShape(); + + if ( theIsBreakLink || geom->_is_nil() ) { SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog ); SALOMEDS::SObject_wrap geomRefSO, geomSO; @@ -2351,22 +2498,23 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) geom = GEOM::GEOM_Object::_narrow( geomObj ); } } - else - { - geom = gog->GetShape(); - } } - if ( !geom->_is_nil() ) + if ( old2newShapeMap.IsBound( group->GetShape() )) { - CORBA::String_var ior = geomGen->GetStringFromIOR( geom ); - geomClient->RemoveShapeFromBuffer( ior.in() ); - groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); - old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); + groupsData.back()._shape = old2newShapeMap( group->GetShape() ); } - else if ( old2newShapeMap.IsBound( group->GetShape() )) + else if ( !geom->_is_nil() ) { - groupsData.back()._shape = old2newShapeMap( group->GetShape() ); + groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); + if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape )) + { + CORBA::String_var ior = geomGen->GetStringFromIOR( geom ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); + } + old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); } + } } // store assigned hypotheses @@ -2379,7 +2527,7 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps )); } - std::map< std::set, int > ii2iMap; // group sub-ids to group id in SMESHDS + std::multimap< std::set, int > ii2iMap; // group sub-ids to group id in SMESHDS // count shapes excluding compounds corresponding to geom groups int oldNbSubShapes = meshDS->MaxShapeIndex(); @@ -2413,20 +2561,43 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) } // re-add shapes (compounds) of geom groups + typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData; + TIndices2GroupData ii2grData; + std::vector< int > ii; std::map< int, int > old2newIDs; // group IDs - std::list::iterator data = _geomGroupData.begin(); - for ( ; data != _geomGroupData.end(); ++data ) + std::list::iterator dataIt = _geomGroupData.begin(); + for ( ; dataIt != _geomGroupData.end(); ++dataIt ) { + TGeomGroupData* data = &(*dataIt); + ii.reserve( data->_indices.size() ); + ii.assign( data->_indices.begin(), data->_indices.end() ); + TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first; + if ( ii2gd->second != data ) + { + data->_groupEntry = ii2gd->second->_groupEntry; + data->_indices = ii2gd->second->_indices; + continue; + } + const int oldNbSub = data->_indices.size(); + const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0; int oldID = 0; - std::map< std::set, int >::iterator ii2i = ii2iMap.find( data->_indices ); + std::multimap< std::set, int >::iterator ii2i = ii2iMap.find( data->_indices ); if ( ii2i != ii2iMap.end() ) + { oldID = ii2i->second; + ii2iMap.erase( ii2i ); + } + if ( !oldID && oldNbSub == 1 ) + oldID = soleOldID; + if ( old2newIDs.count( oldID )) + continue; + + int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED; + newShape = newGroupShape( *data, how ); - int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED; - TopoDS_Shape newShape = newGroupShape( *data, how ); if ( !newShape.IsNull() ) { - if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape + if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape { TopoDS_Compound compound; BRep_Builder().MakeCompound( compound ); @@ -2434,8 +2605,10 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) newShape = compound; } int newID = _impl->GetSubMesh( newShape )->GetId(); - if ( oldID && oldID != newID ) + if ( oldID /*&& oldID != newID*/ ) old2newIDs.insert( std::make_pair( oldID, newID )); + if ( oldNbSub == 1 ) + old2newIDs.insert( std::make_pair( soleOldID, newID )); } } @@ -2443,13 +2616,18 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) for ( size_t i = 0; i < ids2Hyps.size(); ++i ) { int sID = ids2Hyps[i].first; - std::map< int, int >::iterator o2n = old2newIDs.find( sID ); - if ( o2n != old2newIDs.end() ) - sID = o2n->second; - else if ( sID != 1 ) - continue; + if ( sID != 1 ) + { + std::map< int, int >::iterator o2n = old2newIDs.find( sID ); + if ( o2n != old2newIDs.end() ) + sID = o2n->second; + else if ( !sameTopology ) + continue; + } const TopoDS_Shape& s = meshDS->IndexToShape( sID ); - const THypList& hyps = ids2Hyps[i].second; + if ( s.IsNull() ) + continue; + const THypList& hyps = ids2Hyps[i].second; THypList::const_iterator h = hyps.begin(); for ( ; h != hyps.end(); ++h ) _impl->AddHypothesis( s, (*h)->GetID() ); @@ -2476,23 +2654,26 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) g->GetGroupDS()->SetColor( data._color ); } - std::map< int, int >::iterator o2n = old2newIDs.begin(); - for ( ; o2n != old2newIDs.end(); ++o2n ) + if ( !sameTopology ) { - int newID = o2n->second, oldID = o2n->first; - if ( !_mapSubMesh.count( oldID )) - continue; - if ( newID > 0 ) + std::map< int, int >::iterator o2n = old2newIDs.begin(); + for ( ; o2n != old2newIDs.end(); ++o2n ) { - _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID ); - _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; - _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; + int newID = o2n->second, oldID = o2n->first; + if ( newID == oldID || !_mapSubMesh.count( oldID )) + continue; + if ( newID > 0 ) + { + _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID ); + _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; + _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; + } + _mapSubMesh. erase(oldID); + _mapSubMesh_i. erase(oldID); + _mapSubMeshIor.erase(oldID); + if ( newID > 0 ) + _mapSubMesh_i [ newID ]->changeLocalId( newID ); } - _mapSubMesh. erase(oldID); - _mapSubMesh_i. erase(oldID); - _mapSubMeshIor.erase(oldID); - if ( newID > 0 ) - _mapSubMesh_i [ newID ]->changeLocalId( newID ); } // update _mapSubMesh @@ -2509,7 +2690,7 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) _gen_i->UpdateIcons( me ); - if ( !isBreakLink && isShaper ) + if ( !theIsBreakLink && isShaper ) { SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me ); if ( !meshSO->_is_nil() ) @@ -2585,13 +2766,21 @@ void SMESH_Mesh_i::CheckGeomGroupModif() { SMESH::SMESH_GroupBase_ptr group = i_gr->second; ++i_gr; - SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO; + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO; SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group ); SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group ); bool isValidGeom = false; if ( !onGeom->_is_nil() ) { - isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); + isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS + if ( !isValidGeom ) // check reference + { + isValidGeom = ( ! groupSO->_is_nil() && + groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) && + refSO->ReferencedObject( geomSO.inout() ) && + ! geomSO->_is_nil() && + !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() ))); + } } else if ( !onFilt->_is_nil() ) { @@ -2934,11 +3123,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase return aGroup._retn(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Create a sub-mesh on a given sub-shape */ -//============================================================================= +//================================================================================ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject ) { @@ -2984,10 +3173,11 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theS return subMesh._retn(); } -//======================================================================= -//function : getSubMesh -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Return an existing sub-mesh based on a sub-shape with the given ID + */ +//================================================================================ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID) { @@ -2998,11 +3188,11 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID) return SMESH::SMESH_subMesh::_duplicate( (*it).second ); } -//============================================================================= +//================================================================================ /*! - * + * \brief Remove a sub-mesh based on the given sub-shape */ -//============================================================================= +//================================================================================ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Object_ptr theSubShapeObject ) @@ -3064,11 +3254,11 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, return isHypChanged; } -//============================================================================= +//================================================================================ /*! - * + * \brief Create a group. Group type depends on given arguments */ -//============================================================================= +//================================================================================ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType, const char* theName, @@ -3146,11 +3336,11 @@ void SMESH_Mesh_i::removeGroup( const int theId ) } } -//============================================================================= +//================================================================================ /*! - * + * \brief Return a log that can be used to move another mesh to the same state as this one */ -//============================================================================= +//================================================================================ SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) throw(SALOME::SALOME_Exception) @@ -3165,22 +3355,17 @@ SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) 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; @@ -3188,12 +3373,10 @@ SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) aLog[indexLog].indexes.length(inum); for(int i = 0; i < rnum; i++){ aLog[indexLog].coords[i] = *ir; - //MESSAGE(" "<& theRese //============================================================================= /*! - * Sets auto-color mode. If it is on, groups get unique random colors + * Set auto-color mode. If it is on, groups get unique random colors */ //============================================================================= @@ -3449,7 +3631,7 @@ void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOM //============================================================================= /*! - * Returns true if auto-color mode is on + * Return true if auto-color mode is on */ //============================================================================= @@ -3461,7 +3643,7 @@ CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception) //============================================================================= /*! - * Checks if there are groups with equal names + * Check if there are groups with equal names */ //============================================================================= @@ -3513,7 +3695,7 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) //================================================================================ /*! - * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS + * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS * \param file - file name * \param overwrite - to erase the file or not * \retval string - mesh name @@ -4234,6 +4416,12 @@ CORBA::Double SMESH_Mesh_i::GetComputeProgress() return 0.; } +//================================================================================ +/*! + * \brief Return nb of nodes + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -4243,6 +4431,12 @@ CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) return _impl->NbNodes(); } +//================================================================================ +/*! + * \brief Return nb of elements + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -4252,6 +4446,12 @@ CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception) return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls(); } +//================================================================================ +/*! + * \brief Return nb of 0D elements + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -4261,6 +4461,12 @@ CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception) return _impl->Nb0DElements(); } +//================================================================================ +/*! + * \brief Return nb of BALL elements + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -4270,6 +4476,12 @@ CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception) return _impl->NbBalls(); } +//================================================================================ +/*! + * \brief Return nb of 1D elements + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -4279,6 +4491,12 @@ CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception) return _impl->NbEdges(); } +//================================================================================ +/*! + * \brief Return nb of edges + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { @@ -4289,7 +4507,11 @@ CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order) return _impl->NbEdges( (SMDSAbs_ElementOrder) order); } -//============================================================================= +//================================================================================ +/*! + * \brief Return nb of faces + */ +//================================================================================ CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception) { @@ -4300,6 +4522,12 @@ CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception) return _impl->NbFaces(); } +//================================================================================ +/*! + * \brief Return nb of tringles + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -4309,6 +4537,12 @@ CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception) return _impl->NbTriangles(); } +//================================================================================ +/*! + * \brief Return nb of bi-quadratic triangles + */ +//================================================================================ + CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -4510,7 +4744,7 @@ CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order) //============================================================================= /*! - * Returns nb of published sub-meshes + * Return nb of published sub-meshes */ //============================================================================= @@ -4546,7 +4780,7 @@ SMESH::long_array* SMESH_Mesh_i::GetIDs() //============================================================================= /*! - * Returns ids of all elements + * Return ids of all elements */ //============================================================================= @@ -4575,7 +4809,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsId() //============================================================================= /*! - * Returns ids of all elements of given type + * Return ids of all elements of given type */ //============================================================================= @@ -4615,7 +4849,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy //============================================================================= /*! - * Returns ids of all nodes + * Return ids of all nodes */ //============================================================================= @@ -4643,7 +4877,7 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() //============================================================================= /*! - * + * Return type of the given element */ //============================================================================= @@ -4665,7 +4899,7 @@ SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const boo //============================================================================= /*! - * + * Return geometric type of the given element */ //============================================================================= @@ -4684,7 +4918,7 @@ SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id ) //============================================================================= /*! - * + * Return type of the given element */ //============================================================================= @@ -4703,9 +4937,10 @@ SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id ) //============================================================================= /*! - * Returns ID of elements for given submesh + * Return ID of elements for given submesh */ //============================================================================= + SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { @@ -4736,9 +4971,9 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) //============================================================================= /*! - * Returns ID of nodes for given submesh - * If param all==true - returns all nodes, else - - * returns only nodes on shapes. + * Return ID of nodes for given sub-mesh + * If param all==true - return all nodes, else - + * Return only nodes on shapes. */ //============================================================================= @@ -4791,7 +5026,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, //============================================================================= /*! - * Returns type of elements for given submesh + * Return type of elements for given sub-mesh */ //============================================================================= @@ -4826,7 +5061,7 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID //============================================================================= /*! - * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client + * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client */ //============================================================================= @@ -4844,7 +5079,7 @@ CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() //============================================================================= /*! * Get XYZ coordinates of node as list of double - * If there is not node for given ID - returns empty list + * If there is not node for given ID - return empty list */ //============================================================================= @@ -4874,8 +5109,8 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id) //============================================================================= /*! - * For given node returns list of IDs of inverse elements - * If there is not node for given ID - returns empty list + * For given node return list of IDs of inverse elements + * If there is not node for given ID - return empty list */ //============================================================================= @@ -5008,8 +5243,8 @@ SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID) //============================================================================= /*! - * If given element is node returns IDs of shape from position - * If there is not node for given ID - returns -1 + * If given element is node return IDs of shape from position + * If there is not node for given ID - return -1 */ //============================================================================= @@ -5034,9 +5269,9 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) //============================================================================= /*! - * For given element returns ID of result shape after + * For given element return ID of result shape after * ::FindShape() from SMESH_MeshEditor - * If there is not element for given ID - returns -1 + * If there is not element for given ID - return -1 */ //============================================================================= @@ -5065,8 +5300,8 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id) //============================================================================= /*! - * Returns number of nodes for given element - * If there is not element for given ID - returns -1 + * Return number of nodes for given element + * If there is not element for given ID - return -1 */ //============================================================================= @@ -5086,9 +5321,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id) //============================================================================= /*! - * Returns ID of node by given index for given element - * If there is not element for given ID - returns -1 - * If there is not node for given index - returns -2 + * Return ID of node by given index for given element + * If there is not element for given ID - return -1 + * If there is not node for given index - return -2 */ //============================================================================= @@ -5107,7 +5342,7 @@ CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long in //============================================================================= /*! - * Returns IDs of nodes of given element + * Return IDs of nodes of given element */ //============================================================================= @@ -5132,7 +5367,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) //============================================================================= /*! - * Returns true if given node is medium node + * Return true if given node is medium node * in given quadratic element */ //============================================================================= @@ -5157,7 +5392,7 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Lo //============================================================================= /*! - * Returns true if given node is medium node + * Return true if given node is medium node * in one of quadratic elements */ //============================================================================= @@ -5189,7 +5424,7 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn, //============================================================================= /*! - * Returns number of edges for given element + * Return number of edges for given element */ //============================================================================= @@ -5208,7 +5443,7 @@ CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id) //============================================================================= /*! - * Returns number of faces for given element + * Return number of faces for given element */ //============================================================================= @@ -5224,10 +5459,11 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id) return elem->NbFaces(); } -//======================================================================= -//function : GetElemFaceNodes -//purpose : Returns nodes of given face (counted from zero) for given element. -//======================================================================= +//================================================================================ +/*! + * \brief Return nodes of given face (counted from zero) for given element. + */ +//================================================================================ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, CORBA::Short faceIndex) @@ -5253,10 +5489,11 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, return aResult._retn(); } -//======================================================================= -//function : GetFaceNormal -//purpose : Returns three components of normal of given mesh face. -//======================================================================= +//================================================================================ +/*! + * \brief Return three components of normal of given mesh face. + */ +//================================================================================ SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId, CORBA::Boolean normalized) @@ -5280,10 +5517,11 @@ SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId, return aResult._retn(); } -//======================================================================= -//function : FindElementByNodes -//purpose : Returns an element based on all given nodes. -//======================================================================= +//================================================================================ +/*! + * \brief Return an element based on all given nodes. + */ +//================================================================================ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) { @@ -5340,7 +5578,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nod //============================================================================= /*! - * Returns true if given element is polygon + * Return true if given element is polygon */ //============================================================================= @@ -5359,7 +5597,7 @@ CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id) //============================================================================= /*! - * Returns true if given element is quadratic + * Return true if given element is quadratic */ //============================================================================= @@ -5377,7 +5615,7 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id) //============================================================================= /*! - * Returns diameter of ball discrete element or zero in case of an invalid \a id + * Return diameter of ball discrete element or zero in case of an invalid \a id */ //============================================================================= @@ -5395,7 +5633,7 @@ CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id) //============================================================================= /*! - * Returns bary center for given element + * Return bary center for given element */ //============================================================================= @@ -5583,15 +5821,21 @@ void SMESH_Mesh_i::CreateGroupServants() GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape ); _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName()); } + if ( !addedIDs.empty() ) { // python dump - set::iterator id = addedIDs.begin(); - for ( ; id != addedIDs.end(); ++id ) + map::iterator i_grp = _mapGroups.begin(); + for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp ) { - map::iterator it = _mapGroups.find(*id); - int i = std::distance( _mapGroups.begin(), it ); - TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]"; + set::iterator it = addedIDs.find( i_grp->first ); + if ( it != addedIDs.end() ) + { + TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]"; + addedIDs.erase( it ); + if ( addedIDs.empty() ) + break; + } } } } @@ -5725,7 +5969,7 @@ void SMESH_Mesh_i::checkGroupNames() //============================================================================= /*! - * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol + * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol */ //============================================================================= void SMESH_Mesh_i::SetParameters(const char* theParameters) @@ -5736,7 +5980,7 @@ void SMESH_Mesh_i::SetParameters(const char* theParameters) //============================================================================= /*! - * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol + * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol */ //============================================================================= @@ -5747,7 +5991,7 @@ char* SMESH_Mesh_i::GetParameters() //============================================================================= /*! - * \brief Returns list of notebook variables used for last Mesh operation + * \brief Return list of notebook variables used for last Mesh operation */ //============================================================================= SMESH::string_array* SMESH_Mesh_i::GetLastParameters() @@ -5767,10 +6011,11 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() return aResult._retn(); } -//======================================================================= -//function : GetTypes -//purpose : Returns types of elements it contains -//======================================================================= +//================================================================================ +/*! + * \brief Return types of elements it contains + */ +//================================================================================ SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes() { @@ -5793,21 +6038,25 @@ SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes() return types._retn(); } -//======================================================================= -//function : GetMesh -//purpose : Returns self -//======================================================================= +//================================================================================ +/*! + * \brief Return self + */ +//================================================================================ SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _this() ); } -//======================================================================= -//function : IsMeshInfoCorrect -//purpose : * Returns false if GetMeshInfo() returns incorrect information that may -// * happen if mesh data is not yet fully loaded from the file of study. -//======================================================================= +//================================================================================ +/*! + * \brief Return false if GetMeshInfo() return incorrect information that may + * happen if mesh data is not yet fully loaded from the file of study. + * + * + */ +//================================================================================ bool SMESH_Mesh_i::IsMeshInfoCorrect() { @@ -5816,7 +6065,7 @@ bool SMESH_Mesh_i::IsMeshInfoCorrect() //============================================================================= /*! - * \brief Returns number of mesh elements per each \a EntityType + * \brief Return number of mesh elements per each \a EntityType */ //============================================================================= @@ -5840,7 +6089,7 @@ SMESH::long_array* SMESH_Mesh_i::GetMeshInfo() //============================================================================= /*! - * \brief Returns number of mesh elements per each \a ElementType + * \brief Return number of mesh elements per each \a ElementType */ //============================================================================= @@ -5879,7 +6128,7 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, } //============================================================================= /* - * Returns mesh unstructed grid information. + * Return mesh unstructed grid information. */ //============================================================================= @@ -6182,8 +6431,8 @@ class SMESH_DimHyp //! fields int _dim; //!< a dimension the algo can build (concurrent dimension) int _ownDim; //!< dimension of shape of _subMesh (>=_dim) - TopTools_MapOfShape _shapeMap; - SMESH_subMesh* _subMesh; + TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim + const SMESH_subMesh* _subMesh; list _hypotheses; //!< algo is first, then its parameters //----------------------------------------------------------------------------- @@ -6197,7 +6446,7 @@ class SMESH_DimHyp const int theDim, const TopoDS_Shape& theShape) { - _subMesh = (SMESH_subMesh*)theSubMesh; + _subMesh = theSubMesh; SetShape( theDim, theShape ); } @@ -6279,9 +6528,11 @@ class SMESH_DimHyp bool isSame = checkAlgo( a1, a2 ); if ( !isSame ) { - if ( !a1 || !a2 ) - return false; // pb? - return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency ! + return true; + // commented off for IPAL54678 + // if ( !a1 || !a2 ) + // return false; // pb? + // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency ! } // check hypothesises for concurrence (skip first as algorithm) @@ -6322,8 +6573,12 @@ void addDimHypInstance(const int theDim, const list & theHypList, TDimHypList* theDimHypListArr ) { + if ( !theAlgo->NeedDiscreteBoundary() && + theAlgo->NeedLowerHyps( theDim )) // IPAL54678 + return; TDimHypList& listOfdimHyp = theDimHypListArr[theDim]; - if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) { + 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 ); @@ -6379,7 +6634,8 @@ void unionLists(TListOfInt& theListOfId, const int theIndx ) { TListOfListOfInt::iterator it = theListOfListOfId.begin(); - for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) { + for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) + { if ( i < theIndx ) continue; //skip already treated lists // check if other list has any same submesh object @@ -6464,7 +6720,7 @@ CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID) //============================================================================= /*! - * \brief Return submesh objects list in meshing order + * \brief Return sub-mesh objects list in meshing order */ //============================================================================= @@ -6502,81 +6758,86 @@ 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. - // We define the dimensions by algo of each of hypotheses in hypList - list ::const_iterator hypIt = hypList.begin(); - for( ; hypIt != hypList.end(); hypIt++ ) { - SMESH_Algo* anAlgo = 0; - const SMESH_Hypothesis* hyp = dynamic_cast(*hypIt); - if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO ) - // hyp it-self is algo - anAlgo = (SMESH_Algo*)dynamic_cast(hyp); - else { - // try to find algorithm with help of sub-shapes - TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) ); - for ( ; !anAlgo && anExp.More(); anExp.Next() ) - anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() ); - } - if (!anAlgo) - 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()) + // collect submeshes and detect concurrent algorithms and hypothesises + TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension - // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm - for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ ) - addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr ); + 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. + // We define the dimensions by algo of each of hypotheses in hypList + list ::const_iterator hypIt = hypList.begin(); + for( ; hypIt != hypList.end(); hypIt++ ) + { + SMESH_Algo* anAlgo = 0; + const SMESH_Hypothesis* hyp = dynamic_cast(*hypIt); + if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO ) + // hyp it-self is algo + anAlgo = (SMESH_Algo*)dynamic_cast(hyp); + else { + // try to find algorithm with help of sub-shapes + TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) ); + for ( ; !anAlgo && anExp.More(); anExp.Next() ) + anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() ); } - } // end iterations on submesh + if (!anAlgo) + 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() + // and !anAlgo->NeedLowerHyps( dim )) + + // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm + for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ ) + addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr ); + } + } // end iterations on submesh // iterate on created dimension-hypotheses and check for concurrents - for ( int i = 0; i < 4; 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; - TDimHypList listOfConcurr; - set setOfConcurrIds; - // looking for concurrents and collect into own list - for ( int j = i; j < 4; j++ ) - findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds ); - // check if any concurrents found - if ( listOfConcurr.size() > 0 ) { - // add own submesh to list of concurrent - 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 ); - } + for ( int i = 0; i < 4; 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; + TDimHypList listOfConcurr; + set setOfConcurrIds; + // looking for concurrents and collect into own list + for ( int j = i; j < 4; j++ ) + findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds ); + // check if any concurrents found + if ( listOfConcurr.size() > 0 ) + { + // add own submesh to list of concurrent + 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 ); } } + } - removeDimHyps(dimHypListArr); + removeDimHyps(dimHypListArr); - // now, minimize the number of concurrent groups - // Here we assume that lists of submeshes can have same submesh - // in case of multi-dimension algorithms, as result - // list with common submesh has to be united into one list - int listIndx = 0; - TListOfListOfInt::iterator listIt = anOrder.begin(); - for(; listIt != anOrder.end(); listIt++, listIndx++ ) - unionLists( *listIt, anOrder, listIndx + 1 ); - } + // now, minimize the number of concurrent groups + // Here we assume that lists of submeshes can have same submesh + // in case of multi-dimension algorithms, as result + // list with common submesh has to be united into one list + int listIndx = 0; + TListOfListOfInt::iterator listIt = anOrder.begin(); + for(; listIt != anOrder.end(); listIt++, listIndx++ ) + unionLists( *listIt, anOrder, listIndx + 1 ); return anOrder; } @@ -6664,7 +6925,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, theResOrder.length(nbSet); TListOfListOfInt::const_iterator it = theIdsOrder.begin(); int listIndx = 0; - for( ; it != theIdsOrder.end(); it++ ) { + for( ; it != theIdsOrder.end(); it++ ) + { // translate submesh identificators into submesh objects // takeing into account real number of concurrent lists const TListOfInt& aSubOrder = (*it); @@ -6677,7 +6939,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, aResSubSet->length(aSubOrder.size()); TListOfInt::const_iterator subIt = aSubOrder.begin(); int j; - for( j = 0; subIt != aSubOrder.end(); subIt++ ) { + for( j = 0; subIt != aSubOrder.end(); subIt++ ) + { if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() ) continue; SMESH::SMESH_subMesh_var subMesh =