X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Mesh.cxx;h=d39700ed360a2600e4a38aedbf9f059f0d65b4b4;hp=23c5041c787e8599077227603b55244d3e90454e;hb=163dc9b8fdb3977baa5d73c51c7d185a4996b1af;hpb=4ff5bd61540272713e48de1eee75625028c32155 diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 23c5041c7..d39700ed3 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1,31 +1,29 @@ -// SMESH SMESH : implementaion of SMESH idl descriptions +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Mesh.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ - +// #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_Gen.hxx" @@ -35,7 +33,9 @@ #include "SMESHDS_Group.hxx" #include "SMESHDS_Script.hxx" #include "SMESHDS_GroupOnGeom.hxx" +#include "SMESHDS_Document.hxx" #include "SMDS_MeshVolume.hxx" +#include "SMDS_SetIterator.hxx" #include "utilities.h" @@ -48,21 +48,21 @@ #include "DriverUNV_R_SMDS_Mesh.h" #include "DriverSTL_R_SMDS_Mesh.h" -#include -#include -#include - -#include +#undef _Precision_HeaderFile +#include +#include +#include #include -#include -#include +#include #include +#include #include - -#include +#include #include "Utils_ExceptHandlers.hxx" +using namespace std; + // maximum stored group name length in MED file #define MAX_MED_GROUP_NAME_LENGTH 80 @@ -72,6 +72,9 @@ static int MYDEBUG = 0; static int MYDEBUG = 0; #endif +#define cSMESH_Hyp(h) static_cast(h) + +typedef SMESH_HypoFilter THypType; //============================================================================= /*! @@ -79,21 +82,24 @@ static int MYDEBUG = 0; */ //============================================================================= -SMESH_Mesh::SMESH_Mesh(int theLocalId, - int theStudyId, - SMESH_Gen* theGen, - bool theIsEmbeddedMode, - SMESHDS_Document* theDocument): - _groupId( 0 ) -{ - INFOS("SMESH_Mesh::SMESH_Mesh(int localId)"); - _id = theLocalId; - _studyId = theStudyId; - _gen = theGen; - _myDocument = theDocument; - _idDoc = theDocument->NewMesh(theIsEmbeddedMode); - _myMeshDS = theDocument->GetMesh(_idDoc); +SMESH_Mesh::SMESH_Mesh(int theLocalId, + int theStudyId, + SMESH_Gen* theGen, + bool theIsEmbeddedMode, + SMESHDS_Document* theDocument): + _groupId( 0 ), _nbSubShapes( 0 ) +{ + MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)"); + _id = theLocalId; + _studyId = theStudyId; + _gen = theGen; + _myDocument = theDocument; + _idDoc = theDocument->NewMesh(theIsEmbeddedMode); + _myMeshDS = theDocument->GetMesh(_idDoc); _isShapeToMesh = false; + _isAutoColor = false; + _shapeDiagonal = 0.0; + _myMeshDS->ShapeToMesh( PseudoShape() ); } //============================================================================= @@ -106,17 +112,23 @@ SMESH_Mesh::~SMESH_Mesh() { INFOS("SMESH_Mesh::~SMESH_Mesh"); + // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study + // Notify event listeners at least that something happens + if ( SMESH_subMesh * sm = GetSubMeshContaining(1)) + sm->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); + // delete groups map < int, SMESH_Group * >::iterator itg; for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) { SMESH_Group *aGroup = (*itg).second; delete aGroup; } + _mapGroup.clear(); } //============================================================================= /*! - * + * \brief Set geometry to be meshed */ //============================================================================= @@ -124,7 +136,13 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) { if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh"); - if ( !_myMeshDS->ShapeToMesh().IsNull() && aShape.IsNull() ) + if ( !aShape.IsNull() && _isShapeToMesh ) { + if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change + _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND ) + throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined")); + } + // clear current data + if ( !_myMeshDS->ShapeToMesh().IsNull() ) { // removal of a shape to mesh, delete objects referring to sub-shapes: // - sub-meshes @@ -143,28 +161,178 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) else i_gr++; } - _mapPropagationChains.Clear(); + _mapAncestors.Clear(); + + // clear SMESHDS + TopoDS_Shape aNullShape; + _myMeshDS->ShapeToMesh( aNullShape ); + + _shapeDiagonal = 0.0; + } + + // set a new geometry + if ( !aShape.IsNull() ) + { + _myMeshDS->ShapeToMesh(aShape); + _isShapeToMesh = true; + _nbSubShapes = _myMeshDS->MaxShapeIndex(); + + // fill map of ancestors + fillAncestorsMap(aShape); } else { - if (_isShapeToMesh) - throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined")); + _isShapeToMesh = false; + _shapeDiagonal = 0.0; + _myMeshDS->ShapeToMesh( PseudoShape() ); } - _isShapeToMesh = true; - _myMeshDS->ShapeToMesh(aShape); +} - // fill _mapAncestors - _mapAncestors.Clear(); - int desType, ancType; - for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- ) - for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- ) - TopExp::MapShapesAndAncestors ( aShape, - (TopAbs_ShapeEnum) desType, - (TopAbs_ShapeEnum) ancType, - _mapAncestors ); +//======================================================================= +/*! + * \brief Return geometry to be meshed. (It may be a PseudoShape()!) + */ +//======================================================================= + +TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const +{ + return _myMeshDS->ShapeToMesh(); +} + +//======================================================================= +/*! + * \brief Return a solid which is returned by GetShapeToMesh() if + * a real geometry to be meshed was not set + */ +//======================================================================= + +const TopoDS_Solid& SMESH_Mesh::PseudoShape() +{ + static TopoDS_Solid aSolid; + if ( aSolid.IsNull() ) + { + aSolid = BRepPrimAPI_MakeBox(1,1,1); + } + return aSolid; +} + +//======================================================================= +/*! + * \brief Return diagonal size of bounding box of a shape + */ +//======================================================================= + +double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape) +{ + if ( !aShape.IsNull() ) { + Bnd_Box Box; + BRepBndLib::Add(aShape, Box); + return sqrt( Box.SquareExtent() ); + } + return 0; +} + +//======================================================================= +/*! + * \brief Return diagonal size of bounding box of shape to mesh + */ +//======================================================================= + +double SMESH_Mesh::GetShapeDiagonalSize() const +{ + if ( _shapeDiagonal == 0. && _isShapeToMesh ) + const_cast(this)->_shapeDiagonal = GetShapeDiagonalSize( GetShapeToMesh() ); + + return _shapeDiagonal; +} + +//======================================================================= +/*! + * \brief Remove all nodes and elements + */ +//======================================================================= - // NRI : 24/02/03 - //EAP: 1/9/04 TopExp::MapShapes(aShape, _subShapes); USE the same map of _myMeshDS +void SMESH_Mesh::Clear() +{ + // clear mesh data + _myMeshDS->ClearMesh(); + + // update compute state of submeshes + if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) { + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, + /*complexShapeFirst=*/false); + while ( smIt->more() ) { + sm = smIt->next(); + sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + } + } + +// // clear sub-meshes; get ready to re-compute as a side-effect + +// if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) +// { +// SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, +// /*complexShapeFirst=*/false); +// while ( smIt->more() ) +// { +// sm = smIt->next(); +// TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); +// if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID ) +// // all other shapes depends on vertices so they are already cleaned +// sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); +// // to recompute even if failed +// sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); +// } +// } + +// // clear entities not on sub-meshes + +// SMDS_VolumeIteratorPtr vIt = _myMeshDS->volumesIterator(); +// while ( vIt->more() ) +// _myMeshDS->RemoveFreeElement( vIt->next(), 0 ); + +// SMDS_FaceIteratorPtr fIt = _myMeshDS->facesIterator(); +// while ( fIt->more() ) +// _myMeshDS->RemoveFreeElement( fIt->next(), 0 ); + +// SMDS_EdgeIteratorPtr eIt = _myMeshDS->edgesIterator(); +// while ( eIt->more() ) +// _myMeshDS->RemoveFreeElement( eIt->next(), 0 ); + +// SMDS_NodeIteratorPtr nIt = _myMeshDS->nodesIterator(); +// while ( nIt->more() ) { +// const SMDS_MeshNode * node = nIt->next(); +// if ( node->NbInverseElements() == 0 ) +// _myMeshDS->RemoveFreeNode( node, 0 ); +// else +// _myMeshDS->RemoveNode(node); +// } +} + +//======================================================================= +/*! + * \brief Remove all nodes and elements of indicated shape + */ +//======================================================================= + +void SMESH_Mesh::ClearSubMesh(const int theShapeId) +{ + // clear sub-meshes; get ready to re-compute as a side-effect + if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) ) + { + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, + /*complexShapeFirst=*/false); + while ( smIt->more() ) + { + sm = smIt->next(); + TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); + if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID ) + // all other shapes depends on vertices so they are already cleaned + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + // to recompute even if failed + sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + } + } } //======================================================================= @@ -177,17 +345,47 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName) if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<NbNodes() = "<<_myMeshDS->NbNodes()); - MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges()); - MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces()); - MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes()); + MESSAGE("UNVToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes()); + MESSAGE("UNVToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges()); + MESSAGE("UNVToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces()); + MESSAGE("UNVToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes()); + } + SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup(); + if (aGroup != 0) { + TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap(); + //const TGroupIdMap& aGroupId = myReader.GetGroupIdMap(); + aGroup->InitSubGroupsIterator(); + while (aGroup->MoreSubGroups()) { + SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup(); + string aName = aGroupNames[aSubGroup]; + int aId; + + SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId ); + if ( aSMESHGroup ) { + if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<( aSMESHGroup->GetGroupDS() ); + if ( aGroupDS ) { + aGroupDS->SetStoreName(aName.c_str()); + aSubGroup->InitIterator(); + const SMDS_MeshElement* aElement = 0; + while (aSubGroup->More()) { + aElement = aSubGroup->Next(); + if (aElement) { + aGroupDS->SMDSGroup().Add(aElement); + } + } + if (aElement) + aGroupDS->SetType(aElement->GetType()); + } + } + } } return 1; } @@ -202,7 +400,7 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<NbNodes() = "<<_myMeshDS->NbNodes()); - MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges()); - MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces()); - MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes()); + MESSAGE("STLToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes()); + MESSAGE("STLToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges()); + MESSAGE("STLToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces()); + MESSAGE("STLToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes()); } return 1; } @@ -277,29 +475,6 @@ SMESH_Hypothesis::Hypothesis_Status if ( !subMesh || !subMesh->GetId()) return SMESH_Hypothesis::HYP_BAD_SUBSHAPE; - SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); - if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub- - { - MESSAGE("AddHypothesis() to complex submesh"); - // return the worst but not fatal state of all group memebers - SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret; - aBestRet = SMESH_Hypothesis::HYP_BAD_DIM; - aWorstNotFatal = SMESH_Hypothesis::HYP_OK; - for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next()) - { - if ( !GetMeshDS()->ShapeToIndex( itS.Value() )) - continue; // not sub-shape - ret = AddHypothesis( itS.Value(), anHypId ); - if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal ) - aWorstNotFatal = ret; - if ( ret < aBestRet ) - aBestRet = ret; - } - if ( SMESH_Hypothesis::IsStatusFatal( aBestRet )) - return aBestRet; - return aWorstNotFatal; - } - StudyContextStruct *sc = _gen->GetStudyContext(_studyId); if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end()) { @@ -329,21 +504,17 @@ SMESH_Hypothesis::Hypothesis_Status // shape - int event; - if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO) - event = SMESH_subMesh::ADD_HYP; - else - event = SMESH_subMesh::ADD_ALGO; + bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ); + int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP; + SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp); // subShapes if (!SMESH_Hypothesis::IsStatusFatal(ret) && - !subMesh->IsApplicableHypotesis( anHyp )) // is added on father + anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father { - if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO) - event = SMESH_subMesh::ADD_FATHER_HYP; - else - event = SMESH_subMesh::ADD_FATHER_ALGO; + event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP; + SMESH_Hypothesis::Hypothesis_Status ret2 = subMesh->SubMeshesAlgoStateEngine(event, anHyp); if (ret2 > ret) @@ -352,11 +523,11 @@ SMESH_Hypothesis::Hypothesis_Status // check concurent hypotheses on ansestors if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp ) { - const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn(); - map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin(); - for ( ; smIt != smMap.end(); smIt++ ) { - if ( smIt->second->IsApplicableHypotesis( anHyp )) { - ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() ); + SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); + while ( smIt->more() ) { + SMESH_subMesh* sm = smIt->next(); + if ( sm->IsApplicableHypotesis( anHyp )) { + ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() ); if (ret2 > ret) { ret = ret2; break; @@ -384,29 +555,6 @@ SMESH_Hypothesis::Hypothesis_Status Unexpect aCatch(SalomeException); if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis"); - SMESH_subMesh *subMesh = GetSubMesh(aSubShape); - SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); - if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) - { - // return the worst but not fatal state of all group memebers - SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret; - aBestRet = SMESH_Hypothesis::HYP_BAD_DIM; - aWorstNotFatal = SMESH_Hypothesis::HYP_OK; - for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next()) - { - if ( !GetMeshDS()->ShapeToIndex( itS.Value() )) - continue; // not sub-shape - ret = RemoveHypothesis( itS.Value(), anHypId ); - if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal ) - aWorstNotFatal = ret; - if ( ret < aBestRet ) - aBestRet = ret; - } - if ( SMESH_Hypothesis::IsStatusFatal( aBestRet )) - return aBestRet; - return aWorstNotFatal; - } - StudyContextStruct *sc = _gen->GetStudyContext(_studyId); if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end()) throw SALOME_Exception(LOCALIZED("hypothesis does not exist")); @@ -414,14 +562,14 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId]; int hypType = anHyp->GetType(); if(MYDEBUG) SCRUTE(hypType); - int event; // shape - if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO) - event = SMESH_subMesh::REMOVE_HYP; - else - event = SMESH_subMesh::REMOVE_ALGO; + bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ); + int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP; + + SMESH_subMesh *subMesh = GetSubMesh(aSubShape); + SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp); // there may appear concurrent hyps that were covered by the removed hyp @@ -432,12 +580,10 @@ SMESH_Hypothesis::Hypothesis_Status // subShapes if (!SMESH_Hypothesis::IsStatusFatal(ret) && - !subMesh->IsApplicableHypotesis( anHyp )) // is removed from father + anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father { - if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO) - event = SMESH_subMesh::REMOVE_FATHER_HYP; - else - event = SMESH_subMesh::REMOVE_FATHER_ALGO; + event = isAlgo ? SMESH_subMesh::REMOVE_FATHER_ALGO : SMESH_subMesh::REMOVE_FATHER_HYP; + SMESH_Hypothesis::Hypothesis_Status ret2 = subMesh->SubMeshesAlgoStateEngine(event, anHyp); if (ret2 > ret) // more severe @@ -446,11 +592,11 @@ SMESH_Hypothesis::Hypothesis_Status // check concurent hypotheses on ansestors if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) ) { - const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn(); - map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin(); - for ( ; smIt != smMap.end(); smIt++ ) { - if ( smIt->second->IsApplicableHypotesis( anHyp )) { - ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() ); + SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); + while ( smIt->more() ) { + SMESH_subMesh* sm = smIt->next(); + if ( sm->IsApplicableHypotesis( anHyp )) { + ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() ); if (ret2 > ret) { ret = ret2; break; @@ -471,17 +617,6 @@ SMESH_Hypothesis::Hypothesis_Status */ //============================================================================= -SMESHDS_Mesh * SMESH_Mesh::GetMeshDS() -{ - return _myMeshDS; -} - -//============================================================================= -/*! - * - */ -//============================================================================= - const list& SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const throw(SALOME_Exception) @@ -491,45 +626,54 @@ SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const } //======================================================================= -//function : GetHypothesis -//purpose : +/*! + * \brief Return the hypothesis assigned to the shape + * \param aSubShape - the shape to check + * \param aFilter - the hypothesis filter + * \param andAncestors - flag to check hypos assigned to ancestors of the shape + * \param assignedTo - to return the shape the found hypo is assigned to + * \retval SMESH_Hypothesis* - the first hypo passed through aFilter + */ //======================================================================= const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubShape, const SMESH_HypoFilter& aFilter, - const bool andAncestors) const + const bool andAncestors, + TopoDS_Shape* assignedTo) const { { const list& hypList = _myMeshDS->GetHypothesis(aSubShape); list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { - const SMESH_Hypothesis * h = static_cast( *hyp ); - if ( aFilter.IsOk( h, aSubShape)) + const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); + if ( aFilter.IsOk( h, aSubShape)) { + if ( assignedTo ) *assignedTo = aSubShape; return h; + } } } if ( andAncestors ) { - TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - for (; it.More(); it.Next() ) + // user sorted submeshes of ancestors, according to stored submesh priority + const list smList = getAncestorsSubMeshes( aSubShape ); + list::const_iterator smIt = smList.begin(); + for ( ; smIt != smList.end(); smIt++ ) { - const list& hypList = _myMeshDS->GetHypothesis(it.Value()); + const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); + const list& hypList = _myMeshDS->GetHypothesis(curSh); list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { - const SMESH_Hypothesis * h = static_cast( *hyp ); - if (aFilter.IsOk( h, it.Value() )) + const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); + if (aFilter.IsOk( h, curSh )) { + if ( assignedTo ) *assignedTo = curSh; return h; + } } } } return 0; } -//======================================================================= -//function : GetHypotheses -//purpose : -//======================================================================= - //================================================================================ /*! * \brief Return hypothesis assigned to the shape @@ -549,21 +693,30 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, set hypTypes; // to exclude same type hypos from the result list int nbHyps = 0; + // only one main hypothesis is allowed + bool mainHypFound = false; + // fill in hypTypes list::const_iterator hyp; - for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) + for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) { if ( hypTypes.insert( (*hyp)->GetName() ).second ) nbHyps++; + if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() ) + mainHypFound = true; + } // get hypos from aSubShape { const list& hypList = _myMeshDS->GetHypothesis(aSubShape); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) - if ( aFilter.IsOk (static_cast( *hyp ), aSubShape) && + if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) && + ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) && hypTypes.insert( (*hyp)->GetName() ).second ) { aHypList.push_back( *hyp ); nbHyps++; + if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() ) + mainHypFound = true; } } @@ -571,17 +724,25 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, if ( andAncestors ) { TopTools_MapOfShape map; - TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - for (; it.More(); it.Next() ) + + // user sorted submeshes of ancestors, according to stored submesh priority + const list smList = getAncestorsSubMeshes( aSubShape ); + list::const_iterator smIt = smList.begin(); + for ( ; smIt != smList.end(); smIt++ ) { - if ( !map.Add( it.Value() )) + const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); + if ( !map.Add( curSh )) continue; - const list& hypList = _myMeshDS->GetHypothesis(it.Value()); + const list& hypList = _myMeshDS->GetHypothesis(curSh); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) - if (aFilter.IsOk( static_cast( *hyp ), it.Value() ) && - hypTypes.insert( (*hyp)->GetName() ).second ) { + if (aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh ) && + ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) && + hypTypes.insert( (*hyp)->GetName() ).second ) + { aHypList.push_back( *hyp ); nbHyps++; + if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() ) + mainHypFound = true; } } } @@ -613,29 +774,6 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception) _myMeshDS->GetScript()->Clear(); } -//============================================================================= -/*! - * - */ -//============================================================================= - -int SMESH_Mesh::GetId() -{ - if(MYDEBUG) MESSAGE("SMESH_Mesh::GetId"); - return _id; -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -SMESH_Gen *SMESH_Mesh::GetGen() -{ - return _gen; -} - //============================================================================= /*! * Get or Create the SMESH_subMesh object implementation @@ -650,10 +788,16 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) int index = _myMeshDS->ShapeToIndex(aSubShape); // for submeshes on GEOM Group - if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) { + if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) { TopoDS_Iterator it( aSubShape ); if ( it.More() ) + { index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); + if ( index > _nbSubShapes ) _nbSubShapes = index; // not to create sm for this group again + + // fill map of Ancestors + fillAncestorsMap(aSubShape); + } } // if ( !index ) // return NULL; // neither sub-shape nor a group @@ -667,6 +811,7 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) { aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); _mapSubMesh[index] = aSubMesh; + ClearMeshOrder(); } return aSubMesh; } @@ -678,7 +823,7 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) */ //============================================================================= -SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) +SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); @@ -686,13 +831,12 @@ SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) int index = _myMeshDS->ShapeToIndex(aSubShape); - map ::iterator i_sm = _mapSubMesh.find(index); + map ::const_iterator i_sm = _mapSubMesh.find(index); if ( i_sm != _mapSubMesh.end()) aSubMesh = i_sm->second; return aSubMesh; } - //============================================================================= /*! * Get the SMESH_subMesh object implementation. Dont create it, return null @@ -700,17 +844,51 @@ SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) */ //============================================================================= -SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) +SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - map ::iterator i_sm = _mapSubMesh.find(aShapeID); + map ::const_iterator i_sm = _mapSubMesh.find(aShapeID); if (i_sm == _mapSubMesh.end()) return NULL; return i_sm->second; } +//================================================================================ +/*! + * \brief Return submeshes of groups containing the given subshape + */ +//================================================================================ +list +SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const + throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + list found; + + SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape); + if ( !subMesh ) + return found; + + // submeshes of groups have max IDs, so search from the map end + map::const_reverse_iterator i_sm; + for ( i_sm = _mapSubMesh.rbegin(); i_sm != _mapSubMesh.rend(); ++i_sm) { + SMESHDS_SubMesh * ds = i_sm->second->GetSubMeshDS(); + if ( ds && ds->IsComplexSubmesh() ) { + TopExp_Explorer exp( i_sm->second->GetSubShape(), aSubShape.ShapeType() ); + for ( ; exp.More(); exp.Next() ) { + if ( aSubShape.IsSame( exp.Current() )) { + found.push_back( i_sm->second ); + break; + } + } + } else { + break; + } + } + return found; +} //======================================================================= //function : IsUsedHypothesis //purpose : Return True if anHyp is used to mesh aSubShape @@ -778,15 +956,12 @@ SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) //purpose : Say all submeshes using theChangedHyp that it has been modified //======================================================================= -void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp) +void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp) { Unexpect aCatch(SalomeException); - const SMESH_Hypothesis* hyp = static_cast(theChangedHyp); - const SMESH_Algo *foundAlgo = 0; - SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() ); - SMESH_HypoFilter compatibleHypoKind; + SMESH_HypoFilter algoKind, compatibleHypoKind; list usedHyps; @@ -799,7 +974,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* t const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); if ( !foundAlgo ) // init filter for algo search - algoKind.And( algoKind.IsApplicableTo( aSubShape )); + algoKind.Init( THypType::IsAlgo() ).And( THypType::IsApplicableTo( aSubShape )); const SMESH_Algo *algo = static_cast ( GetHypothesis( aSubShape, algoKind, true )); @@ -821,16 +996,31 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* t if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) && find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() ) { - aSubMesh->ComputeStateEngine(SMESH_subMesh::MODIF_HYP); - - if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape )) - CleanMeshOnPropagationChain( aSubShape ); + aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP, + const_cast< SMESH_Hypothesis*>( hyp )); } } } } } +//============================================================================= +/*! + * Auto color functionality + */ +//============================================================================= +void SMESH_Mesh::SetAutoColor(bool theAutoColor) throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + _isAutoColor = theAutoColor; +} + +bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _isAutoColor; +} + //============================================================================= /*! Export* methods. * To store mesh contents on disk in different formats. @@ -839,12 +1029,15 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* t bool SMESH_Mesh::HasDuplicatedGroupNamesMED() { - set aGroupNames; - for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + //set aGroupNames; // Corrected for Mantis issue 0020028 + map< SMDSAbs_ElementType, set > aGroupNames; + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) + { SMESH_Group* aGroup = it->second; + SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType(); string aGroupName = aGroup->GetName(); aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); - if (!aGroupNames.insert(aGroupName).second) + if (!aGroupNames[aType].insert(aGroupName).second) return true; } @@ -852,9 +1045,9 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED() } void SMESH_Mesh::ExportMED(const char *file, - const char* theMeshName, - bool theAutoGroups, - int theVersion) + const char* theMeshName, + bool theAutoGroups, + int theVersion) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); @@ -877,17 +1070,19 @@ void SMESH_Mesh::ExportMED(const char *file, } // Pass groups to writer. Provide unique group names. - set aGroupNames; + //set aGroupNames; // Corrected for Mantis issue 0020028 + map< SMDSAbs_ElementType, set > aGroupNames; char aString [256]; int maxNbIter = 10000; // to guarantee cycle finish for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { SMESH_Group* aGroup = it->second; SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); if ( aGroupDS ) { + SMDSAbs_ElementType aType = aGroupDS->GetType(); string aGroupName0 = aGroup->GetName(); aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH); string aGroupName = aGroupName0; - for (int i = 1; !aGroupNames.insert(aGroupName).second && i < maxNbIter; i++) { + for (int i = 1; !aGroupNames[aType].insert(aGroupName).second && i < maxNbIter; i++) { sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str()); aGroupName = aString; aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); @@ -918,6 +1113,17 @@ void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception) myWriter.SetFile(string(file)); myWriter.SetMesh(_myMeshDS); myWriter.SetMeshId(_idDoc); + // myWriter.SetGroups(_mapGroup); + + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + SMESH_Group* aGroup = it->second; + SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); + if ( aGroupDS ) { + string aGroupName = aGroup->GetName(); + aGroupDS->SetStoreName( aGroupName.c_str() ); + myWriter.AddGroup( aGroupDS ); + } + } myWriter.Perform(); } @@ -932,176 +1138,168 @@ void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Ex myWriter.Perform(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Return number of nodes in the mesh */ -//============================================================================= +//================================================================================ + int SMESH_Mesh::NbNodes() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->NbNodes(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Return number of edges of given order in the mesh */ -//============================================================================= -int SMESH_Mesh::NbEdges() throw(SALOME_Exception) +//================================================================================ + +int SMESH_Mesh::Nb0DElements() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - return _myMeshDS->NbEdges(); + return _myMeshDS->GetMeshInfo().Nb0DElements(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Return number of edges of given order in the mesh */ -//============================================================================= -int SMESH_Mesh::NbFaces() throw(SALOME_Exception) +//================================================================================ + +int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - return _myMeshDS->NbFaces(); + return _myMeshDS->GetMeshInfo().NbEdges(order); } -/////////////////////////////////////////////////////////////////////////////// -/// Return the number of 3 nodes faces in the mesh. This method run in O(n) -/////////////////////////////////////////////////////////////////////////////// -int SMESH_Mesh::NbTriangles() throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Return number of faces of given order in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - - SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator(); - //while(itFaces->more()) if(itFaces->next()->NbNodes()==3) Nb++; - const SMDS_MeshFace * curFace; - while (itFaces->more()) { - curFace = itFaces->next(); - if ( !curFace->IsPoly() && - ( curFace->NbNodes()==3 || curFace->NbNodes()==6 ) ) Nb++; - } - return Nb; + return _myMeshDS->GetMeshInfo().NbFaces(order); +} + +//================================================================================ +/*! + * \brief Return the number of faces in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbTriangles(order); } -/////////////////////////////////////////////////////////////////////////////// -/// Return the number of 4 nodes faces in the mesh. This method run in O(n) -/////////////////////////////////////////////////////////////////////////////// -int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Return the number nodes faces in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - - SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator(); - //while(itFaces->more()) if(itFaces->next()->NbNodes()==4) Nb++; - const SMDS_MeshFace * curFace; - while (itFaces->more()) { - curFace = itFaces->next(); - if ( !curFace->IsPoly() && - ( curFace->NbNodes() == 4 || curFace->NbNodes()==8 ) ) Nb++; - } - return Nb; + return _myMeshDS->GetMeshInfo().NbQuadrangles(order); } -/////////////////////////////////////////////////////////////////////////////// -/// Return the number of polygonal faces in the mesh. This method run in O(n) -/////////////////////////////////////////////////////////////////////////////// +//================================================================================ +/*! + * \brief Return the number of polygonal faces in the mesh + */ +//================================================================================ + int SMESH_Mesh::NbPolygons() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - SMDS_FaceIteratorPtr itFaces = _myMeshDS->facesIterator(); - while (itFaces->more()) - if (itFaces->next()->IsPoly()) Nb++; - return Nb; + return _myMeshDS->GetMeshInfo().NbPolygons(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Return number of volumes of given order in the mesh */ -//============================================================================= -int SMESH_Mesh::NbVolumes() throw(SALOME_Exception) +//================================================================================ + +int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - return _myMeshDS->NbVolumes(); + return _myMeshDS->GetMeshInfo().NbVolumes(order); } -int SMESH_Mesh::NbTetras() throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Return number of tetrahedrons of given order in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); - //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==4) Nb++; - const SMDS_MeshVolume * curVolume; - while (itVolumes->more()) { - curVolume = itVolumes->next(); - if ( !curVolume->IsPoly() && - ( curVolume->NbNodes() == 4 || curVolume->NbNodes()==10 ) ) Nb++; - } - return Nb; + return _myMeshDS->GetMeshInfo().NbTetras(order); } -int SMESH_Mesh::NbHexas() throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Return number of hexahedrons of given order in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); - //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==8) Nb++; - const SMDS_MeshVolume * curVolume; - while (itVolumes->more()) { - curVolume = itVolumes->next(); - if ( !curVolume->IsPoly() && - ( curVolume->NbNodes() == 8 || curVolume->NbNodes()==20 ) ) Nb++; - } - return Nb; + return _myMeshDS->GetMeshInfo().NbHexas(order); } -int SMESH_Mesh::NbPyramids() throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Return number of pyramids of given order in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); - //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==5) Nb++; - const SMDS_MeshVolume * curVolume; - while (itVolumes->more()) { - curVolume = itVolumes->next(); - if ( !curVolume->IsPoly() && - ( curVolume->NbNodes() == 5 || curVolume->NbNodes()==13 ) ) Nb++; - } - return Nb; + return _myMeshDS->GetMeshInfo().NbPyramids(order); } -int SMESH_Mesh::NbPrisms() throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Return number of prisms (penthahedrons) of given order in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); - //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==6) Nb++; - const SMDS_MeshVolume * curVolume; - while (itVolumes->more()) { - curVolume = itVolumes->next(); - if ( !curVolume->IsPoly() && - ( curVolume->NbNodes() == 6 || curVolume->NbNodes()==15 ) ) Nb++; - } - return Nb; + return _myMeshDS->GetMeshInfo().NbPrisms(order); } +//================================================================================ +/*! + * \brief Return number of polyhedrons in the mesh + */ +//================================================================================ + int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - int Nb = 0; - SMDS_VolumeIteratorPtr itVolumes = _myMeshDS->volumesIterator(); - while (itVolumes->more()) - if (itVolumes->next()->IsPoly()) Nb++; - return Nb; + return _myMeshDS->GetMeshInfo().NbPolyhedrons(); } -//============================================================================= +//================================================================================ /*! - * + * \brief Return number of submeshes in the mesh */ -//============================================================================= +//================================================================================ + int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); @@ -1117,7 +1315,7 @@ bool SMESH_Mesh::IsNotConformAllowed() const { if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed"); - SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" )); + static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" )); return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false ); } @@ -1139,7 +1337,7 @@ bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType, const char* theName, - int& theId, + int& theId, const TopoDS_Shape& theShape) { if (_mapGroup.find(_groupId) != _mapGroup.end()) @@ -1151,9 +1349,21 @@ SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType, return aGroup; } +//================================================================================ +/*! + * \brief Return iterator on all existing groups + */ +//================================================================================ + +SMESH_Mesh::GroupIteratorPtr SMESH_Mesh::GetGroups() const +{ + typedef map TMap; + return GroupIteratorPtr( new SMDS_mapIterator( _mapGroup )); +} + //============================================================================= /*! - * + * \brief Return a group by ID */ //============================================================================= @@ -1167,11 +1377,11 @@ SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID) //============================================================================= /*! - * + * \brief Return IDs of all groups */ //============================================================================= -list SMESH_Mesh::GetGroupIds() +list SMESH_Mesh::GetGroupIds() const { list anIds; for ( map::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) @@ -1196,358 +1406,260 @@ void SMESH_Mesh::RemoveGroup (const int theGroupID) _mapGroup.erase (theGroupID); } -//============================================================================= -/*! - * IsLocal1DHypothesis - * Returns a local 1D hypothesis used for theEdge - */ -//============================================================================= -const SMESH_Hypothesis* SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge) +//======================================================================= +//function : GetAncestors +//purpose : return list of ancestors of theSubShape in the order +// that lower dimention shapes come first. +//======================================================================= + +const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const { - SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 )); - hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( GetMeshDS()->ShapeToMesh() )); + if ( _mapAncestors.Contains( theS ) ) + return _mapAncestors.FindFromKey( theS ); - return GetHypothesis( theEdge, hypo, true ); + static TopTools_ListOfShape emptyList; + return emptyList; } -//============================================================================= -/*! - * IsPropagationHypothesis - */ -//============================================================================= -bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge) +//======================================================================= +//function : Dump +//purpose : dumps contents of mesh to stream [ debug purposes ] +//======================================================================= + +ostream& SMESH_Mesh::Dump(ostream& save) { - return _mapPropagationChains.Contains(theEdge); + int clause = 0; + save << "========================== Dump contents of mesh ==========================" << endl << endl; + save << ++clause << ") Total number of nodes: \t" << NbNodes() << endl; + save << ++clause << ") Total number of edges: \t" << NbEdges() << endl; + save << ++clause << ") Total number of faces: \t" << NbFaces() << endl; + save << ++clause << ") Total number of polygons:\t" << NbPolygons() << endl; + save << ++clause << ") Total number of volumes:\t" << NbVolumes() << endl; + save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl; + for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic ) + { + string orderStr = isQuadratic ? "quadratic" : "linear"; + SMDSAbs_ElementOrder order = isQuadratic ? ORDER_QUADRATIC : ORDER_LINEAR; + + save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl; + save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl; + if ( NbFaces(order) > 0 ) { + int nb3 = NbTriangles(order); + int nb4 = NbQuadrangles(order); + save << clause << ".1) Number of " << orderStr << " triangles: \t" << nb3 << endl; + save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl; + if ( nb3 + nb4 != NbFaces(order) ) { + map myFaceMap; + SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator(); + while( itFaces->more( ) ) { + int nbNodes = itFaces->next()->NbNodes(); + if ( myFaceMap.find( nbNodes ) == myFaceMap.end() ) + myFaceMap[ nbNodes ] = 0; + myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1; + } + save << clause << ".3) Faces in detail: " << endl; + map ::iterator itF; + for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++) + save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl; + } + } + save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl; + if ( NbVolumes(order) > 0 ) { + int nb8 = NbHexas(order); + int nb4 = NbTetras(order); + int nb5 = NbPyramids(order); + int nb6 = NbPrisms(order); + save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl; + save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl; + save << clause << ".3) Number of " << orderStr << " prisms: \t" << nb6 << endl; + save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl; + if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) { + map myVolumesMap; + SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); + while( itVolumes->more( ) ) { + int nbNodes = itVolumes->next()->NbNodes(); + if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() ) + myVolumesMap[ nbNodes ] = 0; + myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1; + } + save << clause << ".5) Volumes in detail: " << endl; + map ::iterator itV; + for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++) + save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl; + } + } + save << endl; + } + save << "===========================================================================" << endl; + return save; +} + +//======================================================================= +//function : GetElementType +//purpose : Returns type of mesh element with certain id +//======================================================================= + +SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem ) +{ + return _myMeshDS->GetElementType( id, iselem ); } //============================================================================= /*! - * IsPropagatedHypothesis + * \brief Convert group on geometry into standalone group */ //============================================================================= -bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge, - TopoDS_Shape& theMainEdge) -{ - int nbChains = _mapPropagationChains.Extent(); - for (int i = 1; i <= nbChains; i++) { - //const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i); - const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i); - if (aChain.Contains(theEdge)) { - theMainEdge = _mapPropagationChains.FindKey(i); - return true; - } - } - return false; +SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID ) +{ + SMESH_Group* aGroup = 0; + map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID ); + if ( itg == _mapGroup.end() ) + return aGroup; + + SMESH_Group* anOldGrp = (*itg).second; + SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS(); + if ( !anOldGrp || !anOldGrpDS ) + return aGroup; + + // create new standalone group + aGroup = new SMESH_Group (theGroupID, this, anOldGrpDS->GetType(), anOldGrp->GetName() ); + _mapGroup[theGroupID] = aGroup; + + SMESHDS_Group* aNewGrpDS = dynamic_cast( aGroup->GetGroupDS() ); + GetMeshDS()->RemoveGroup( anOldGrpDS ); + GetMeshDS()->AddGroup( aNewGrpDS ); + + // add elements (or nodes) into new created group + SMDS_ElemIteratorPtr anItr = anOldGrpDS->GetElements(); + while ( anItr->more() ) + aNewGrpDS->Add( (anItr->next())->GetID() ); + + // remove old group + delete anOldGrp; + + return aGroup; } + //============================================================================= /*! - * IsReversedInChain + * \brief remove submesh order from Mesh */ //============================================================================= -bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge, - const TopoDS_Shape& theMainEdge) +void SMESH_Mesh::ClearMeshOrder() { - if ( !theMainEdge.IsNull() && !theEdge.IsNull() && - _mapPropagationChains.Contains( theMainEdge )) - { - const SMESH_IndexedMapOfShape& aChain = - _mapPropagationChains.FindFromKey( theMainEdge ); - int index = aChain.FindIndex( theEdge ); - if ( index ) - return aChain(index).Orientation() == TopAbs_REVERSED; - } - return false; + _mySubMeshOrder.clear(); } //============================================================================= /*! - * CleanMeshOnPropagationChain + * \brief remove submesh order from Mesh */ //============================================================================= -void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge) -{ - const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge); - int i, nbEdges = aChain.Extent(); - for (i = 1; i <= nbEdges; i++) { - TopoDS_Shape anEdge = aChain.FindKey(i); - SMESH_subMesh *subMesh = GetSubMesh(anEdge); - SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); - if (subMeshDS && subMeshDS->NbElements() > 0) { - subMesh->ComputeStateEngine(SMESH_subMesh::CLEAN); - } - } + +void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder ) +{ + _mySubMeshOrder = theOrder; } //============================================================================= /*! - * RebuildPropagationChains - * Rebuild all existing propagation chains. - * Have to be used, if 1D hypothesis have been assigned/removed to/from any edge + * \brief return submesh order if any */ //============================================================================= -bool SMESH_Mesh::RebuildPropagationChains() -{ - bool ret = true; - - // Clean all chains, because they can be not up-to-date - int i, nbChains = _mapPropagationChains.Extent(); - for (i = 1; i <= nbChains; i++) { - TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i); - CleanMeshOnPropagationChain(aMainEdge); - _mapPropagationChains.ChangeFromIndex(i).Clear(); - } - - // Build all chains - for (i = 1; i <= nbChains; i++) { - TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i); - if (!BuildPropagationChain(aMainEdge)) - ret = false; - CleanMeshOnPropagationChain(aMainEdge); - } - return ret; +const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const +{ + return _mySubMeshOrder; } //============================================================================= /*! - * RemovePropagationChain - * Have to be used, if Propagation hypothesis is removed from + * \brief fillAncestorsMap */ //============================================================================= -bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge) -{ - if (!_mapPropagationChains.Contains(theMainEdge)) - return false; - // Clean mesh elements and nodes, built on the chain - CleanMeshOnPropagationChain(theMainEdge); - - // Clean the chain - _mapPropagationChains.ChangeFromKey(theMainEdge).Clear(); - - // Remove the chain from the map - int i = _mapPropagationChains.FindIndex(theMainEdge); - if ( i == _mapPropagationChains.Extent() ) - _mapPropagationChains.RemoveLast(); - else { - TopoDS_Vertex anEmptyShape; - BRep_Builder BB; - BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1); - SMESH_IndexedMapOfShape anEmptyMap; - _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap); - } - - return true; +void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) +{ + // fill _mapAncestors + int desType, ancType; + for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- ) + for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- ) + TopExp::MapShapesAndAncestors ( theShape, + (TopAbs_ShapeEnum) desType, + (TopAbs_ShapeEnum) ancType, + _mapAncestors ); } //============================================================================= /*! - * BuildPropagationChain + * \brief sort submeshes according to stored mesh order + * \param theListToSort in out list to be sorted + * \return FALSE if nothing sorted */ //============================================================================= -bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) -{ - if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; - - // Add new chain, if there is no - if (!_mapPropagationChains.Contains(theMainEdge)) { - SMESH_IndexedMapOfShape aNewChain; - _mapPropagationChains.Add(theMainEdge, aNewChain); - } - // Check presence of 1D hypothesis to be propagated - const SMESH_Hypothesis* aMainHyp = IsLocal1DHypothesis(theMainEdge); - if (!aMainHyp) { - MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign."); +bool SMESH_Mesh::SortByMeshOrder(list& theListToSort) const +{ + if ( !_mySubMeshOrder.size() || theListToSort.size() < 2) return true; + + bool res = false; + list onlyOrderedList; + // collect all ordered submeshes in one list as pointers + // and get their positions within theListToSort + typedef list::iterator TPosInList; + map< int, TPosInList > sortedPos; + TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end(); + TListOfListOfInt::const_iterator listIddIt = _mySubMeshOrder.begin(); + for( ; listIddIt != _mySubMeshOrder.end(); listIddIt++) { + const TListOfInt& listOfId = *listIddIt; + TListOfInt::const_iterator idIt = listOfId.begin(); + for ( ; idIt != listOfId.end(); idIt++ ) { + if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) { + TPosInList smPos = find( smBeg, smEnd, sm ); + if ( smPos != smEnd ) { + onlyOrderedList.push_back( sm ); + sortedPos[ distance( smBeg, smPos )] = smPos; + } + } + } } + if (onlyOrderedList.size() < 2) + return res; + res = true; - // Edges, on which the 1D hypothesis will be propagated from - SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge); - if (aChain.Extent() > 0) { - CleanMeshOnPropagationChain(theMainEdge); - aChain.Clear(); - } + list::iterator onlyBIt = onlyOrderedList.begin(); + list::iterator onlyEIt = onlyOrderedList.end(); - // At first put in the chain - aChain.Add(theMainEdge); - - // List of edges, added to chain on the previous cycle pass - TopTools_ListOfShape listPrevEdges; - listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD )); - -// 5____4____3____4____5____6 -// | | | | | | -// | | | | | | -// 4____3____2____3____4____5 -// | | | | | | Number in the each knot of -// | | | | | | grid indicates cycle pass, -// 3____2____1____2____3____4 on which corresponding edge -// | | | | | | (perpendicular to the plane -// | | | | | | of view) will be found. -// 2____1____0____1____2____3 -// | | | | | | -// | | | | | | -// 3____2____1____2____3____4 - - // Collect all edges pass by pass - while (listPrevEdges.Extent() > 0) { - // List of edges, added to chain on this cycle pass - TopTools_ListOfShape listCurEdges; - - // Find the next portion of edges - TopTools_ListIteratorOfListOfShape itE (listPrevEdges); - for (; itE.More(); itE.Next()) { - TopoDS_Shape anE = itE.Value(); - - // Iterate on faces, having edge - TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE)); - for (; itA.More(); itA.Next()) { - TopoDS_Shape aW = itA.Value(); - - // There are objects of different type among the ancestors of edge - if (aW.ShapeType() == TopAbs_WIRE) { - TopoDS_Shape anOppE; - - BRepTools_WireExplorer aWE (TopoDS::Wire(aW)); - Standard_Integer nb = 1, found = 0; - TopTools_Array1OfShape anEdges (1,4); - for (; aWE.More(); aWE.Next(), nb++) { - if (nb > 4) { - found = 0; - break; - } - anEdges(nb) = aWE.Current(); - if (!_mapAncestors.Contains(anEdges(nb))) { - MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!"); - break; - } - if (anEdges(nb).IsSame(anE)) found = nb; - } + // iterates on ordered submeshes and insert them in detected positions + map< int, TPosInList >::iterator i_pos = sortedPos.begin(); + for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos ) + *(i_pos->second) = *onlyBIt; - if (nb == 5 && found > 0) { - // Quadrangle face found, get an opposite edge - Standard_Integer opp = found + 2; - if (opp > 4) opp -= 4; - anOppE = anEdges(opp); - - // add anOppE to aChain if ... - if (!aChain.Contains(anOppE)) { // ... anOppE is not in aChain - if (!IsLocal1DHypothesis(anOppE)) { // ... no other 1d hyp on anOppE - TopoDS_Shape aMainEdgeForOppEdge; // ... no other hyp is propagated to anOppE - if (!IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge)) - { - // Add found edge to the chain oriented so that to - // have it co-directed with a forward MainEdge - TopAbs_Orientation ori = anE.Orientation(); - if ( anEdges(opp).Orientation() == anEdges(found).Orientation() ) - ori = TopAbs::Reverse( ori ); - anOppE.Orientation( ori ); - aChain.Add(anOppE); - listCurEdges.Append(anOppE); - } - else { - // Collision! - MESSAGE("Error: Collision between propagated hypotheses"); - CleanMeshOnPropagationChain(theMainEdge); - aChain.Clear(); - return ( aMainHyp == IsLocal1DHypothesis(aMainEdgeForOppEdge) ); - } - } - } - } // if (nb == 5 && found > 0) - } // if (aF.ShapeType() == TopAbs_WIRE) - } // for (; itF.More(); itF.Next()) - } // for (; itE.More(); itE.Next()) - - listPrevEdges = listCurEdges; - } // while (listPrevEdges.Extent() > 0) - - CleanMeshOnPropagationChain(theMainEdge); - return true; + return res; } -//======================================================================= -//function : GetAncestors -//purpose : return list of ancestors of theSubShape in the order -// that lower dimention shapes come first. -//======================================================================= +//============================================================================= +/*! + * \brief sort submeshes according to stored mesh order + * \param theListToSort in out list to be sorted + * \return FALSE if nothing sorted + */ +//============================================================================= -const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const +list SMESH_Mesh::getAncestorsSubMeshes + (const TopoDS_Shape& theSubShape) const { - if ( _mapAncestors.Contains( theS ) ) - return _mapAncestors.FindFromKey( theS ); + list listOfSubMesh; + TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape )); + for (; it.More(); it.Next() ) + if ( SMESH_subMesh* sm = GetSubMeshContaining( it.Value() )) + listOfSubMesh.push_back(sm); - static TopTools_ListOfShape emptyList; - return emptyList; -} + // sort submeshes according to stored mesh order + SortByMeshOrder( listOfSubMesh ); -//======================================================================= -//function : Dump -//purpose : dumps contents of mesh to stream [ debug purposes ] -//======================================================================= -ostream& SMESH_Mesh::Dump(ostream& save) -{ - save << "========================== Dump contents of mesh ==========================" << endl; - save << "1) Total number of nodes: " << NbNodes() << endl; - save << "2) Total number of edges: " << NbEdges() << endl; - save << "3) Total number of faces: " << NbFaces() << endl; - if ( NbFaces() > 0 ) { - int nb3 = NbTriangles(); - int nb4 = NbQuadrangles(); - save << "3.1.) Number of triangles: " << nb3 << endl; - save << "3.2.) Number of quadrangles: " << nb4 << endl; - if ( nb3 + nb4 != NbFaces() ) { - map myFaceMap; - SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator(); - while( itFaces->more( ) ) { - int nbNodes = itFaces->next()->NbNodes(); - if ( myFaceMap.find( nbNodes ) == myFaceMap.end() ) - myFaceMap[ nbNodes ] = 0; - myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1; - } - save << "3.3.) Faces in detail: " << endl; - map ::iterator itF; - for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++) - save << "--> nb nodes: " << itF->first << " - nb elemens: " << itF->second << endl; - } - } - save << "4) Total number of volumes: " << NbVolumes() << endl; - if ( NbVolumes() > 0 ) { - int nb8 = NbHexas(); - int nb4 = NbTetras(); - int nb5 = NbPyramids(); - int nb6 = NbPrisms(); - save << "4.1.) Number of hexahedrons: " << nb8 << endl; - save << "4.2.) Number of tetrahedrons: " << nb4 << endl; - save << "4.3.) Number of prisms: " << nb6 << endl; - save << "4.4.) Number of pyramides: " << nb5 << endl; - if ( nb8 + nb4 + nb5 + nb6 != NbVolumes() ) { - map myVolumesMap; - SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); - while( itVolumes->more( ) ) { - int nbNodes = itVolumes->next()->NbNodes(); - if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() ) - myVolumesMap[ nbNodes ] = 0; - myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1; - } - save << "4.5.) Volumes in detail: " << endl; - map ::iterator itV; - for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++) - save << "--> nb nodes: " << itV->first << " - nb elemens: " << itV->second << endl; - } - } - save << "===========================================================================" << endl; - return save; -} - -//======================================================================= -//function : GetElementType -//purpose : Returns type of mesh element with certain id -//======================================================================= -SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem ) -{ - return _myMeshDS->GetElementType( id, iselem ); + return listOfSubMesh; }