X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FSMESH%2FSMESH_Mesh.cxx;h=bb88ca0bd9ffee65dcde1fb812833c3f7d068292;hb=c3dcb1d5ce71049bef3434d77e015095d92ff646;hp=eb0f0392df127cf163d191336af218de0d2e3ea9;hpb=6d13ce68630daaa8550bdb324a5da08529a82450;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index eb0f0392d..bb88ca0bd 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 // // // @@ -31,6 +31,7 @@ #include "SMESH_Gen.hxx" #include "SMESH_Hypothesis.hxx" #include "SMESH_Group.hxx" +#include "SMESH_HypoFilter.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Script.hxx" #include "SMESHDS_GroupOnGeom.hxx" @@ -56,11 +57,15 @@ #include #include #include +#include #include #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 @@ -74,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; } //============================================================================= @@ -134,7 +143,6 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) else i_gr++; } - _mapAncestors.Clear(); _mapPropagationChains.Clear(); } else @@ -144,6 +152,17 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) } _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 ); + // NRI : 24/02/03 //EAP: 1/9/04 TopExp::MapShapes(aShape, _subShapes); USE the same map of _myMeshDS } @@ -165,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; } @@ -198,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 ); } } @@ -222,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; } @@ -254,15 +304,21 @@ 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() ) + 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; @@ -368,6 +424,8 @@ SMESH_Hypothesis::Hypothesis_Status 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; @@ -462,6 +520,104 @@ SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const return _myMeshDS->GetHypothesis(aSubShape); } +//======================================================================= +//function : GetHypothesis +//purpose : +//======================================================================= + +const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubShape, + const SMESH_HypoFilter& aFilter, + const bool andAncestors) 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)) + return h; + } + } + if ( andAncestors ) + { + TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); + for (; it.More(); it.Next() ) + { + const list& hypList = _myMeshDS->GetHypothesis(it.Value()); + list::const_iterator hyp = hypList.begin(); + for ( ; hyp != hypList.end(); hyp++ ) { + const SMESH_Hypothesis * h = static_cast( *hyp ); + if (aFilter.IsOk( h, it.Value() )) + return h; + } + } + } + return 0; +} + +//======================================================================= +//function : GetHypotheses +//purpose : +//======================================================================= + +//================================================================================ +/*! + * \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 +{ + 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); + for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) + if ( aFilter.IsOk (static_cast( *hyp ), aSubShape) && + hypTypes.insert( (*hyp)->GetName() ).second ) + { + aHypList.push_back( *hyp ); + nbHyps++; + } + } + + // get hypos from ancestors of aSubShape + if ( andAncestors ) + { + TopTools_MapOfShape map; + TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); + for (; it.More(); it.Next() ) + { + if ( !map.Add( it.Value() )) + continue; + const list& hypList = _myMeshDS->GetHypothesis(it.Value()); + 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 nbHyps; +} + //============================================================================= /*! * @@ -517,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; } @@ -550,38 +709,55 @@ 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; } +//============================================================================= +/*! + * Get the SMESH_subMesh object implementation. Dont create it, return null + * if it does not exist. + */ +//============================================================================= + +SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) +throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + + map ::iterator i_sm = _mapSubMesh.find(aShapeID); + if (i_sm == _mapSubMesh.end()) + return NULL; + return i_sm->second; +} + //======================================================================= //function : IsUsedHypothesis //purpose : Return True if anHyp is used to mesh aSubShape //======================================================================= bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, - const TopoDS_Shape & aSubShape) + const SMESH_subMesh* aSubMesh) { - // check if anHyp is applicable to aSubShape - SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape ); - if (!subMesh || - !subMesh->IsApplicableHypotesis(static_cast(anHyp))) + SMESH_Hypothesis* hyp = static_cast(anHyp); + + // 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) @@ -591,41 +767,18 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, if (algo) { // look trough hypotheses used by algo - const list &usedHyps = - algo->GetUsedHypothesis(*this, aSubShape); - list ::const_iterator itl; - for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++) - if (anHyp == (*itl)) - return true; - } - else - { - // look through all assigned hypotheses - { - const list &usedHyps = - _myMeshDS->GetHypothesis( aSubShape ); - list ::const_iterator itl; - for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++) - if (anHyp == (*itl)) - return true; - } - - // on ancestors - TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - for (; it.More(); it.Next()) - { - const list &usedHyps = - _myMeshDS->GetHypothesis( aSubShape ); - list ::const_iterator itl; - for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++) - if (anHyp == (*itl)) - return true; + 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() ); } } - - return false; -} + // look through all assigned hypotheses + //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp )); + return false; //GetHypothesis( aSubShape, filter, true ); +} //============================================================================= /*! @@ -634,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, @@ -663,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 ); @@ -680,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(); } @@ -709,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(); } @@ -739,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; } //============================================================================= @@ -750,35 +1011,75 @@ 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++; + while (itFaces->more()) { + 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; } /////////////////////////////////////////////////////////////////////////////// /// 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++; + while (itFaces->more()) { + 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; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of polygonal faces in the mesh. This method run in O(n) +/////////////////////////////////////////////////////////////////////////////// +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; } @@ -787,45 +1088,98 @@ int SMESH_Mesh::NbQuadrangles() 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++; + while (itVolumes->more()) { + 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++; + while (itVolumes->more()) { + 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++; + while (itVolumes->more()) { + 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++; + while (itVolumes->more()) { + 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; +} + +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; } @@ -849,18 +1203,8 @@ bool SMESH_Mesh::IsNotConformAllowed() const { if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed"); - const list& listHyp = - _myMeshDS->GetHypothesis( _myMeshDS->ShapeToMesh() ); - list::const_iterator it=listHyp.begin(); - while (it!=listHyp.end()) - { - const SMESHDS_Hypothesis *aHyp = *it; - string hypName = aHyp->GetName(); - if ( hypName == "NotConformAllowed" ) - return true; - it++; - } - return false; + SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" )); + return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false ); } //======================================================================= @@ -934,30 +1278,22 @@ 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); } //============================================================================= /*! * IsLocal1DHypothesis - * Check, if there is 1D hypothesis assigned directly on + * Returns a local 1D hypothesis used for theEdge */ //============================================================================= -bool SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge) +const SMESH_Hypothesis* SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge) { - const SMESHDS_Mesh* meshDS = GetMeshDS(); - const list& listHyp = meshDS->GetHypothesis(theEdge); - list::const_iterator it = listHyp.begin(); - - for (; it != listHyp.end(); it++) { - const SMESH_Hypothesis * aHyp = static_cast(*it); - if (aHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO && - aHyp->GetDim() == 1) { // 1D Hypothesis found - return true; - } - } - return false; + SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 )); + hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( GetMeshDS()->ShapeToMesh() )); + + return GetHypothesis( theEdge, hypo, true ); } //============================================================================= @@ -980,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; @@ -1001,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 ) @@ -1017,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); } } } @@ -1078,11 +1415,15 @@ bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge) // Remove the chain from the map int i = _mapPropagationChains.FindIndex(theMainEdge); - TopoDS_Vertex anEmptyShape; - BRep_Builder BB; - BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1); - TopTools_IndexedMapOfShape anEmptyMap; - _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap); + 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; } @@ -1098,18 +1439,19 @@ 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); } // Check presence of 1D hypothesis to be propagated - if (!IsLocal1DHypothesis(theMainEdge)) { + const SMESH_Hypothesis* aMainHyp = IsLocal1DHypothesis(theMainEdge); + if (!aMainHyp) { MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign."); return true; } // 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(); @@ -1177,18 +1519,14 @@ bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) if (opp > 4) opp -= 4; anOppE = anEdges(opp); - if (!aChain.Contains(anOppE)) { - if (!IsLocal1DHypothesis(anOppE)) { - TopoDS_Shape aMainEdgeForOppEdge; - if (IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge)) { - // Collision! - MESSAGE("Error: Collision between propagated hypotheses"); - CleanMeshOnPropagationChain(theMainEdge); - aChain.Clear(); - return false; - } else { + // 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 in aChain co-directed with theMainEdge + // have it co-directed with a forward MainEdge TopAbs_Orientation ori = anE.Orientation(); if ( anEdges(opp).Orientation() == anEdges(found).Orientation() ) ori = TopAbs::Reverse( ori ); @@ -1196,6 +1534,13 @@ bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) 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) @@ -1216,20 +1561,8 @@ bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) // that lower dimention shapes come first. //======================================================================= -const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) +const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const { - if ( _mapAncestors.IsEmpty() ) - { - // fill _mapAncestors - int desType, ancType; - for ( desType = TopAbs_EDGE; desType > TopAbs_COMPOUND; desType-- ) - for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- ) - TopExp::MapShapesAndAncestors (_myMeshDS->ShapeToMesh(), - (TopAbs_ShapeEnum) desType, - (TopAbs_ShapeEnum) ancType, - _mapAncestors ); - } - if ( _mapAncestors.Contains( theS ) ) return _mapAncestors.FindFromKey( theS ); @@ -1295,3 +1628,12 @@ ostream& SMESH_Mesh::Dump(ostream& save) 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 ); +}