X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Mesh.cxx;h=a56b7a82629198113822ba7002b24c507119dd6a;hp=8622faec56ff35b218ba2235fce7b8f7f357eb82;hb=104ff7b2818ce4d0f8a38d840abd3e5c70190668;hpb=3291e2c4e1f98a5f37c397c06c254b7ba0f75e9d diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 8622faec5..a56b7a826 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -17,7 +17,7 @@ // 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // // @@ -63,6 +63,9 @@ #include "Utils_ExceptHandlers.hxx" +// maximum stored group name length in MED file +#define MAX_MED_GROUP_NAME_LENGTH 80 + #ifdef _DEBUG_ static int MYDEBUG = 0; #else @@ -76,17 +79,21 @@ static int MYDEBUG = 0; */ //============================================================================= -SMESH_Mesh::SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, SMESHDS_Document * myDocument) -: _groupId( 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 = localId; - _studyId = studyId; - _gen = gen; - _myDocument = myDocument; - _idDoc = _myDocument->NewMesh(); - _myMeshDS = _myDocument->GetMesh(_idDoc); - _isShapeToMesh = false; + _id = theLocalId; + _studyId = theStudyId; + _gen = theGen; + _myDocument = theDocument; + _idDoc = theDocument->NewMesh(theIsEmbeddedMode); + _myMeshDS = theDocument->GetMesh(_idDoc); + _isShapeToMesh = false; } //============================================================================= @@ -149,7 +156,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) // fill _mapAncestors _mapAncestors.Clear(); int desType, ancType; - for ( desType = TopAbs_EDGE; desType > TopAbs_COMPOUND; desType-- ) + for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- ) for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- ) TopExp::MapShapesAndAncestors ( aShape, (TopAbs_ShapeEnum) desType, @@ -177,10 +184,40 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName) myReader.SetMeshId(-1); myReader.Perform(); if(MYDEBUG){ - MESSAGE("MEDToMesh - _myMeshDS->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(); + std::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; } @@ -210,16 +247,17 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) } // Reading groups (sub-meshes are out of scope of MED import functionality) - list aGroupNames = myReader.GetGroupNames(); + list aGroupNames = myReader.GetGroupNamesAndTypes(); if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<::iterator it = aGroupNames.begin(); it != aGroupNames.end(); it++ ) { - SMESH_Group* aGroup = AddGroup( SMDSAbs_All, it->c_str(), anId ); + list::iterator name_type = aGroupNames.begin(); + for ( ; name_type != aGroupNames.end(); name_type++ ) { + SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId ); if ( aGroup ) { - if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<c_str()); + if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<first.c_str()); SMESHDS_Group* aGroupDS = dynamic_cast( aGroup->GetGroupDS() ); if ( aGroupDS ) { - aGroupDS->SetStoreName( it->c_str() ); + aGroupDS->SetStoreName( name_type->first.c_str() ); myReader.GetGroup( aGroupDS ); } } @@ -234,7 +272,7 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) int SMESH_Mesh::STLToMesh(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("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; } @@ -266,6 +304,9 @@ SMESH_Hypothesis::Hypothesis_Status if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis"); SMESH_subMesh *subMesh = GetSubMesh(aSubShape); + 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- { @@ -519,45 +560,62 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubS //purpose : //======================================================================= -bool SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, - const SMESH_HypoFilter& aFilter, - list & aHypList, - const bool andAncestors) const +//================================================================================ +/*! + * \brief Return hypothesis assigned to the shape + * \param aSubShape - the shape to check + * \param aFilter - the hypothesis filter + * \param aHypList - the list of the found hypotheses + * \param andAncestors - flag to check hypos assigned to ancestors of the shape + * \retval int - number of unique hypos in aHypList + */ +//================================================================================ + +int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, + const SMESH_HypoFilter& aFilter, + list & aHypList, + const bool andAncestors) const { - int nbHyp = 0; + set hypTypes; // to exclude same type hypos from the result list + int nbHyps = 0; + + // fill in hypTypes + list::const_iterator hyp; + for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) + if ( hypTypes.insert( (*hyp)->GetName() ).second ) + nbHyps++; + + // get hypos from aSubShape { const list& hypList = _myMeshDS->GetHypothesis(aSubShape); - list::const_iterator hyp = hypList.begin(); - for ( ; hyp != hypList.end(); hyp++ ) - if ( aFilter.IsOk (static_cast( *hyp ), aSubShape)) { + for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) + if ( aFilter.IsOk (static_cast( *hyp ), aSubShape) && + hypTypes.insert( (*hyp)->GetName() ).second ) + { aHypList.push_back( *hyp ); - nbHyp++; + nbHyps++; } } - // get hypos from shape of one type only: if any hypo is found on edge, do - // not look up on faces - if ( !nbHyp && andAncestors ) + + // get hypos from ancestors of aSubShape + if ( andAncestors ) { TopTools_MapOfShape map; TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - int shapeType = it.More() ? it.Value().ShapeType() : TopAbs_SHAPE; for (; it.More(); it.Next() ) { - if ( nbHyp && shapeType != it.Value().ShapeType() ) - break; - shapeType = it.Value().ShapeType(); - if ( !map.Add( it.Value() )) + if ( !map.Add( it.Value() )) continue; const list& hypList = _myMeshDS->GetHypothesis(it.Value()); - list::const_iterator hyp = hypList.begin(); - for ( ; hyp != hypList.end(); hyp++ ) - if (aFilter.IsOk( static_cast( *hyp ), it.Value() )) { - aHypList.push_back( *hyp ); - nbHyp++; - } + for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) + if (aFilter.IsOk( static_cast( *hyp ), it.Value() ) && + hypTypes.insert( (*hyp)->GetName() ).second ) { + aHypList.push_back( *hyp ); + nbHyps++; + } } } - return nbHyp; + return nbHyps; } //============================================================================= @@ -615,28 +673,31 @@ SMESH_Gen *SMESH_Mesh::GetGen() //============================================================================= SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) -throw(SALOME_Exception) + throw(SALOME_Exception) { Unexpect aCatch(SalomeException); SMESH_subMesh *aSubMesh; int index = _myMeshDS->ShapeToIndex(aSubShape); - + // for submeshes on GEOM Group if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) { TopoDS_Iterator it( aSubShape ); if ( it.More() ) index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); } +// if ( !index ) +// return NULL; // neither sub-shape nor a group - if (_mapSubMesh.find(index) != _mapSubMesh.end()) - { - aSubMesh = _mapSubMesh[index]; - } + map ::iterator i_sm = _mapSubMesh.find(index); + if ( i_sm != _mapSubMesh.end()) + { + aSubMesh = i_sm->second; + } else - { - aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); - _mapSubMesh[index] = aSubMesh; - } + { + aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); + _mapSubMesh[index] = aSubMesh; + } return aSubMesh; } @@ -648,20 +709,17 @@ throw(SALOME_Exception) //============================================================================= SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) -throw(SALOME_Exception) + throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - bool isFound = false; SMESH_subMesh *aSubMesh = NULL; int index = _myMeshDS->ShapeToIndex(aSubShape); - if (_mapSubMesh.find(index) != _mapSubMesh.end()) - { - aSubMesh = _mapSubMesh[index]; - isFound = true; - } - if (!isFound) - aSubMesh = NULL; + + map ::iterator i_sm = _mapSubMesh.find(index); + if ( i_sm != _mapSubMesh.end()) + aSubMesh = i_sm->second; + return aSubMesh; } @@ -689,15 +747,17 @@ throw(SALOME_Exception) //======================================================================= bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, - const TopoDS_Shape & aSubShape) + const SMESH_subMesh* aSubMesh) { SMESH_Hypothesis* hyp = static_cast(anHyp); - // check if anHyp is applicable to aSubShape - SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape ); - if ( !subMesh || !subMesh->IsApplicableHypotesis( hyp )) + + // check if anHyp can be used to mesh aSubMesh + if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp )) return false; - SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape); + const TopoDS_Shape & aSubShape = const_cast( aSubMesh )->GetSubShape(); + + SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape ); // algorithm if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO) @@ -707,17 +767,19 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, if (algo) { // look trough hypotheses used by algo - const list &usedHyps = - algo->GetUsedHypothesis(*this, aSubShape); - return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() ); + SMESH_HypoFilter hypoKind; + if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) { + list usedHyps; + if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true )) + return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() ); + } } // look through all assigned hypotheses - SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp )); - return GetHypothesis( aSubShape, filter, true ); + //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp )); + return false; //GetHypothesis( aSubShape, filter, true ); } - //============================================================================= /*! * @@ -725,28 +787,100 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, //============================================================================= const list < SMESH_subMesh * >& - SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) -throw(SALOME_Exception) +SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) + throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis"); - map < int, SMESH_subMesh * >::iterator itsm; - _subMeshesUsingHypothesisList.clear(); - for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) - { - SMESH_subMesh *aSubMesh = (*itsm).second; - if ( IsUsedHypothesis ( anHyp, aSubMesh->GetSubShape() )) - _subMeshesUsingHypothesisList.push_back(aSubMesh); - } - return _subMeshesUsingHypothesisList; + if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis"); + map < int, SMESH_subMesh * >::iterator itsm; + _subMeshesUsingHypothesisList.clear(); + for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) + { + SMESH_subMesh *aSubMesh = (*itsm).second; + if ( IsUsedHypothesis ( anHyp, aSubMesh )) + _subMeshesUsingHypothesisList.push_back(aSubMesh); + } + return _subMeshesUsingHypothesisList; +} + +//======================================================================= +//function : NotifySubMeshesHypothesisModification +//purpose : Say all submeshes using theChangedHyp that it has been modified +//======================================================================= + +void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp) +{ + Unexpect aCatch(SalomeException); + + const SMESH_Hypothesis* hyp = static_cast(theChangedHyp); + + const SMESH_Algo *foundAlgo = 0; + SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() ); + SMESH_HypoFilter compatibleHypoKind; + list usedHyps; + + + map < int, SMESH_subMesh * >::iterator itsm; + for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) + { + SMESH_subMesh *aSubMesh = (*itsm).second; + if ( aSubMesh->IsApplicableHypotesis( hyp )) + { + const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); + + if ( !foundAlgo ) // init filter for algo search + algoKind.And( algoKind.IsApplicableTo( aSubShape )); + + const SMESH_Algo *algo = static_cast + ( GetHypothesis( aSubShape, algoKind, true )); + + if ( algo ) + { + bool sameAlgo = ( algo == foundAlgo ); + if ( !sameAlgo && foundAlgo ) + sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0); + + if ( !sameAlgo ) { // init filter for used hypos search + if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() )) + continue; // algo does not use any hypothesis + foundAlgo = algo; + } + + // check if hyp is used by algo + usedHyps.clear(); + 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 ); + } + } + } + } } //============================================================================= -/*! - * +/*! Export* methods. + * To store mesh contents on disk in different formats. */ //============================================================================= +bool SMESH_Mesh::HasDuplicatedGroupNamesMED() +{ + set aGroupNames; + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + SMESH_Group* aGroup = it->second; + string aGroupName = aGroup->GetName(); + aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); + if (!aGroupNames.insert(aGroupName).second) + return true; + } + + return false; +} + void SMESH_Mesh::ExportMED(const char *file, const char* theMeshName, bool theAutoGroups, @@ -754,6 +888,7 @@ void SMESH_Mesh::ExportMED(const char *file, throw(SALOME_Exception) { Unexpect aCatch(SalomeException); + DriverMED_W_SMESHDS_Mesh myWriter; myWriter.SetFile ( file, MED::EVersion(theVersion) ); myWriter.SetMesh ( _myMeshDS ); @@ -771,15 +906,28 @@ void SMESH_Mesh::ExportMED(const char *file, myWriter.AddGroupOfVolumes(); } + // Pass groups to writer. Provide unique group names. + 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 ) { - aGroupDS->SetStoreName( aGroup->GetName() ); + 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++) { + sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str()); + aGroupName = aString; + aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); + } + aGroupDS->SetStoreName( aGroupName.c_str() ); myWriter.AddGroup( aGroupDS ); } } + // Perform export myWriter.Perform(); } @@ -800,6 +948,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(); } @@ -830,10 +989,21 @@ int SMESH_Mesh::NbNodes() throw(SALOME_Exception) * */ //============================================================================= -int SMESH_Mesh::NbEdges() throw(SALOME_Exception) +int SMESH_Mesh::NbEdges(ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - return _myMeshDS->NbEdges(); + if (order == ORDER_ANY) + return _myMeshDS->NbEdges(); + + int Nb = 0; + SMDS_EdgeIteratorPtr it = _myMeshDS->edgesIterator(); + while (it->more()) { + const SMDS_MeshEdge* cur = it->next(); + if ( order == ORDER_LINEAR && !cur->IsQuadratic() || + order == ORDER_QUADRATIC && cur->IsQuadratic() ) + Nb++; + } + return Nb; } //============================================================================= @@ -841,26 +1011,40 @@ int SMESH_Mesh::NbEdges() throw(SALOME_Exception) * */ //============================================================================= -int SMESH_Mesh::NbFaces() throw(SALOME_Exception) +int SMESH_Mesh::NbFaces(ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - return _myMeshDS->NbFaces(); + if (order == ORDER_ANY) + return _myMeshDS->NbFaces(); + + int Nb = 0; + SMDS_FaceIteratorPtr it = _myMeshDS->facesIterator(); + while (it->more()) { + const SMDS_MeshFace* cur = it->next(); + if ( order == ORDER_LINEAR && !cur->IsQuadratic() || + order == ORDER_QUADRATIC && cur->IsQuadratic() ) + Nb++; + } + return Nb; } /////////////////////////////////////////////////////////////////////////////// /// Return the number of 3 nodes faces in the mesh. This method run in O(n) /////////////////////////////////////////////////////////////////////////////// -int SMESH_Mesh::NbTriangles() throw(SALOME_Exception) +int SMESH_Mesh::NbTriangles(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) Nb++; + const SMDS_MeshFace* curFace = itFaces->next(); + int nbnod = curFace->NbNodes(); + if ( !curFace->IsPoly() && + ( order == ORDER_ANY && (nbnod==3 || nbnod==6) || + order == ORDER_LINEAR && nbnod==3 || + order == ORDER_QUADRATIC && nbnod==6 ) ) + Nb++; } return Nb; } @@ -868,17 +1052,20 @@ int SMESH_Mesh::NbTriangles() throw(SALOME_Exception) /////////////////////////////////////////////////////////////////////////////// /// Return the number of 4 nodes faces in the mesh. This method run in O(n) /////////////////////////////////////////////////////////////////////////////// -int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception) +int SMESH_Mesh::NbQuadrangles(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) Nb++; + const SMDS_MeshFace* curFace = itFaces->next(); + int nbnod = curFace->NbNodes(); + if ( !curFace->IsPoly() && + ( order == ORDER_ANY && (nbnod==4 || nbnod==8) || + order == ORDER_LINEAR && nbnod==4 || + order == ORDER_QUADRATIC && nbnod==8 ) ) + Nb++; } return Nb; } @@ -901,64 +1088,87 @@ int SMESH_Mesh::NbPolygons() throw(SALOME_Exception) * */ //============================================================================= -int SMESH_Mesh::NbVolumes() throw(SALOME_Exception) +int SMESH_Mesh::NbVolumes(ElementOrder order) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - return _myMeshDS->NbVolumes(); + if (order == ORDER_ANY) + return _myMeshDS->NbVolumes(); + + int Nb = 0; + SMDS_VolumeIteratorPtr it = _myMeshDS->volumesIterator(); + while (it->more()) { + const SMDS_MeshVolume* cur = it->next(); + if ( order == ORDER_LINEAR && !cur->IsQuadratic() || + order == ORDER_QUADRATIC && cur->IsQuadratic() ) + Nb++; + } + return Nb; } -int SMESH_Mesh::NbTetras() throw(SALOME_Exception) +int SMESH_Mesh::NbTetras(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) Nb++; + const SMDS_MeshVolume* curVolume = itVolumes->next(); + int nbnod = curVolume->NbNodes(); + if ( !curVolume->IsPoly() && + ( order == ORDER_ANY && (nbnod==4 || nbnod==10) || + order == ORDER_LINEAR && nbnod==4 || + order == ORDER_QUADRATIC && nbnod==10 ) ) + Nb++; } return Nb; } -int SMESH_Mesh::NbHexas() throw(SALOME_Exception) +int SMESH_Mesh::NbHexas(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) Nb++; + const SMDS_MeshVolume* curVolume = itVolumes->next(); + int nbnod = curVolume->NbNodes(); + if ( !curVolume->IsPoly() && + ( order == ORDER_ANY && (nbnod==8 || nbnod==20) || + order == ORDER_LINEAR && nbnod==8 || + order == ORDER_QUADRATIC && nbnod==20 ) ) + Nb++; } return Nb; } -int SMESH_Mesh::NbPyramids() throw(SALOME_Exception) +int SMESH_Mesh::NbPyramids(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) Nb++; + const SMDS_MeshVolume* curVolume = itVolumes->next(); + int nbnod = curVolume->NbNodes(); + if ( !curVolume->IsPoly() && + ( order == ORDER_ANY && (nbnod==5 || nbnod==13) || + order == ORDER_LINEAR && nbnod==5 || + order == ORDER_QUADRATIC && nbnod==13 ) ) + Nb++; } return Nb; } -int SMESH_Mesh::NbPrisms() throw(SALOME_Exception) +int SMESH_Mesh::NbPrisms(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) Nb++; + const SMDS_MeshVolume* curVolume = itVolumes->next(); + int nbnod = curVolume->NbNodes(); + if ( !curVolume->IsPoly() && + ( order == ORDER_ANY && (nbnod==6 || nbnod==15) || + order == ORDER_LINEAR && nbnod==6 || + order == ORDER_QUADRATIC && nbnod==15 ) ) + Nb++; } return Nb; } @@ -1068,8 +1278,8 @@ void SMESH_Mesh::RemoveGroup (const int theGroupID) if (_mapGroup.find(theGroupID) == _mapGroup.end()) return; GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() ); - _mapGroup.erase (theGroupID); delete _mapGroup[theGroupID]; + _mapGroup.erase (theGroupID); } //============================================================================= @@ -1106,7 +1316,8 @@ bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge, { int nbChains = _mapPropagationChains.Extent(); for (int i = 1; i <= nbChains; i++) { - const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(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; @@ -1127,7 +1338,7 @@ bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge, if ( !theMainEdge.IsNull() && !theEdge.IsNull() && _mapPropagationChains.Contains( theMainEdge )) { - const TopTools_IndexedMapOfShape& aChain = + const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey( theMainEdge ); int index = aChain.FindIndex( theEdge ); if ( index ) @@ -1143,14 +1354,14 @@ bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge, //============================================================================= void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge) { - const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(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::CLEANDEP); + subMesh->ComputeStateEngine(SMESH_subMesh::CLEAN); } } } @@ -1210,7 +1421,7 @@ bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge) TopoDS_Vertex anEmptyShape; BRep_Builder BB; BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1); - TopTools_IndexedMapOfShape anEmptyMap; + SMESH_IndexedMapOfShape anEmptyMap; _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap); } @@ -1228,7 +1439,7 @@ bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) // Add new chain, if there is no if (!_mapPropagationChains.Contains(theMainEdge)) { - TopTools_IndexedMapOfShape aNewChain; + SMESH_IndexedMapOfShape aNewChain; _mapPropagationChains.Add(theMainEdge, aNewChain); } @@ -1240,7 +1451,7 @@ bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) } // Edges, on which the 1D hypothesis will be propagated from - TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge); + SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge); if (aChain.Extent() > 0) { CleanMeshOnPropagationChain(theMainEdge); aChain.Clear(); @@ -1365,54 +1576,67 @@ const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) c //======================================================================= 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; + 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"; + 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 << "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 << ++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 << "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; } save << "===========================================================================" << endl; return save;