X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_subMesh.cxx;h=67aeddf531a3fb698f0fbeceac0406637d2b22c1;hb=9ebce0b2a6bd3cfbc327bb42243212117104b917;hp=6b358d32961ce3e1bf1106b2c088e96175631533;hpb=105d08dcbf56b4bec6d8dbe0e5f5ca9b06b9e5fd;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 6b358d329..67aeddf53 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -44,20 +44,34 @@ #include #include #include -#include #include #include -#include -#include #include #include #include +#include +#include -#include +#include #include using namespace std; +//============================================================================= +/*! + * \brief Allocate some memory at construction and release it at destruction. + * Is used to be able to continue working after mesh generation breaks due to + * lack of memory + */ +//============================================================================= + +struct MemoryReserve +{ + char* myBuf; + MemoryReserve(): myBuf( new char[1024*1024*2] ){} + ~MemoryReserve() { delete [] myBuf; } +}; + //============================================================================= /*! * default constructor: @@ -397,10 +411,12 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_SOLID: { //MESSAGE("solid"); - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); - exp.Next()) - { - InsertDependence(exp.Current()); + if(_father->HasShapeToMesh()) { + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); + exp.Next()) + { + InsertDependence(exp.Current()); + } } break; } @@ -481,9 +497,14 @@ const TopoDS_Shape & SMESH_subMesh::GetSubShape() const bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) const { int aHypDim = theHypothesis->GetDim(); - int aShapeDim = SMESH_Gen::GetShapeDim(_subShape); - if ( aHypDim <= aShapeDim ) - return true; + if(_father->HasShapeToMesh()) { + int aShapeDim = SMESH_Gen::GetShapeDim(_subShape); + if ( aHypDim <= aShapeDim ) + return true; + } + else + //Only 3D hypothesis may be assigned to the mesh w/o geometry + return aHypDim == 3; // if ( aHypDim < aShapeDim ) // return ( _father->IsMainShape( _subShape )); @@ -586,8 +607,9 @@ SMESH_Hypothesis::Hypothesis_Status // check if a shape needed by algo is present // ------------------------------------------- algo = static_cast< SMESH_Algo* >( anHyp ); - if ( !_father->HasShapeToMesh() && algo->NeedShape() ) - return SMESH_Hypothesis::HYP_BAD_GEOMETRY; + if(_father->GetShapeToMesh() != SMESH_Mesh::PseudoShape()) + if ( !_father->HasShapeToMesh() && algo->NeedShape() ) + return SMESH_Hypothesis::HYP_BAD_GEOMETRY; // ---------------------- // check mesh conformity // ---------------------- @@ -603,54 +625,22 @@ SMESH_Hypothesis::Hypothesis_Status if ( ! CanAddHypothesis( anHyp )) // check dimension return SMESH_Hypothesis::HYP_BAD_DIM; + if(anHyp->GetDim() == 3 && !_father->HasShapeToMesh() + && event == ADD_ALGO) { + //Only NETGEN_3D and GHS3D_3D can be assigned to the Mesh w/o geometryy + bool isNetgen3D = (strcmp( "NETGEN_3D", anHyp->GetName()) == 0); + bool isGhs3d = (strcmp( "GHS3D_3D", anHyp->GetName()) == 0); + if( !isNetgen3D && !isGhs3d) + return SMESH_Hypothesis::HYP_BAD_DIM; + } + + + if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) ) return SMESH_Hypothesis::HYP_ALREADY_EXIST; if ( !meshDS->AddHypothesis(_subShape, anHyp)) return SMESH_Hypothesis::HYP_ALREADY_EXIST; - - // Serve Propagation of 1D hypothesis - // NOTE: it is possible to re-implement Propagation using EventListener - if (event == ADD_HYP) { - bool isPropagationOk = true; - bool isPropagationHyp = ( strcmp( "Propagation", anHyp->GetName() ) == 0 ); - - if ( isPropagationHyp ) { - TopExp_Explorer exp (_subShape, TopAbs_EDGE); - TopTools_MapOfShape aMap; - for (; exp.More(); exp.Next()) { - if (aMap.Add(exp.Current())) { - if (!_father->BuildPropagationChain(exp.Current())) { - isPropagationOk = false; - } - } - } - } - else if (anHyp->GetDim() == 1) { // Only 1D hypothesis can be propagated - TopExp_Explorer exp (_subShape, TopAbs_EDGE); - TopTools_MapOfShape aMap; - for (; exp.More(); exp.Next()) { - if (aMap.Add(exp.Current())) { - TopoDS_Shape aMainEdge; - if (_father->IsPropagatedHypothesis(exp.Current(), aMainEdge)) { - isPropagationOk = _father->RebuildPropagationChains(); - } else if (_father->IsPropagationHypothesis(exp.Current())) { - isPropagationOk = _father->BuildPropagationChain(exp.Current()); - } else { - } - } - } - } else { - } - - if ( isPropagationOk ) { - if ( isPropagationHyp ) - return ret; // nothing more to do for "Propagation" hypothesis - } - else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { - ret = SMESH_Hypothesis::HYP_CONCURENT; - } - } // Serve Propagation of 1D hypothesis } // -------------------------- @@ -661,45 +651,7 @@ SMESH_Hypothesis::Hypothesis_Status if (!meshDS->RemoveHypothesis(_subShape, anHyp)) return SMESH_Hypothesis::HYP_OK; // nothing changes - // Serve Propagation of 1D hypothesis - // NOTE: it is possible to re-implement Propagation using EventListener - if (event == REMOVE_HYP) - { - bool isPropagationOk = true; - SMESH_HypoFilter propagFilter( SMESH_HypoFilter::HasName( "Propagation" )); - bool isPropagationHyp = propagFilter.IsOk( anHyp, _subShape ); - - if ( isPropagationHyp ) - { - TopExp_Explorer exp (_subShape, TopAbs_EDGE); - TopTools_MapOfShape aMap; - for (; exp.More(); exp.Next()) { - if (aMap.Add(exp.Current()) && - !_father->GetHypothesis( exp.Current(), propagFilter, true )) { - // no more Propagation on the current edge - if (!_father->RemovePropagationChain(exp.Current())) { - return SMESH_Hypothesis::HYP_UNKNOWN_FATAL; - } - } - } - // rebuild propagation chains, because removing one - // chain can resolve concurention, existing before - isPropagationOk = _father->RebuildPropagationChains(); - } - else if (anHyp->GetDim() == 1) // Only 1D hypothesis can be propagated - { - isPropagationOk = _father->RebuildPropagationChains(); - } - - if ( isPropagationOk ) { - if ( isPropagationHyp ) - return ret; // nothing more to do for "Propagation" hypothesis - } - else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { - ret = SMESH_Hypothesis::HYP_CONCURENT; - } - } // Serve Propagation of 1D hypothesis - else // event == REMOVE_ALGO + if (event == REMOVE_ALGO) { algo = dynamic_cast (anHyp); if (!algo->NeedDescretBoundary()) @@ -1365,7 +1317,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = FAILED_TO_COMPUTE; if ( !algo->NeedDescretBoundary() ) _computeError = - SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,"Unexpected submesh",algo); + SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH, + "Unexpected computed submesh",algo); break; } } @@ -1381,10 +1334,12 @@ bool SMESH_subMesh::ComputeStateEngine(int event) OCC_CATCH_SIGNALS; #endif algo->InitComputeError(); + MemoryReserve aMemoryReserve; + SMDS_Mesh::CheckMemory(); if ( !_father->HasShapeToMesh() ) // no shape { SMESH_MesherHelper helper( *_father ); - helper.SetSubShape( _subShape ); + helper.SetSubShape( shape ); helper.SetElementsOnShape( true ); ret = algo->Compute(*_father, &helper ); } @@ -1393,34 +1348,43 @@ bool SMESH_subMesh::ComputeStateEngine(int event) if (!algo->OnlyUnaryInput()) { shape = GetCollection( gen, algo ); } - if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput()) { - ret = ApplyToCollection( algo, shape ); - break; - } - else { - ret = algo->Compute((*_father), shape); - } + ret = algo->Compute((*_father), shape); } if ( !ret ) _computeError = algo->GetComputeError(); } - catch (Standard_Failure& exc) { + catch ( std::bad_alloc& exc ) { + printf("std::bad_alloc thrown inside algo->Compute()\n"); + if ( _computeError ) { + _computeError->myName = COMPERR_MEMORY_PB; + //_computeError->myComment = exc.what(); + } + cleanSubMesh( this ); + throw exc; + } + catch ( Standard_OutOfMemory& exc ) { + printf("Standard_OutOfMemory thrown inside algo->Compute()\n"); + if ( _computeError ) { + _computeError->myName = COMPERR_MEMORY_PB; + //_computeError->myComment = exc.what(); + } + cleanSubMesh( this ); + throw std::bad_alloc(); + } + catch (Standard_Failure& ex) { if ( !_computeError ) _computeError = SMESH_ComputeError::New(); _computeError->myName = COMPERR_OCC_EXCEPTION; - _computeError->myComment = exc.GetMessageString(); + _computeError->myComment += ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) { + _computeError->myComment += ": "; + _computeError->myComment += ex.GetMessageString(); + } } catch ( SALOME_Exception& S_ex ) { if ( !_computeError ) _computeError = SMESH_ComputeError::New(); _computeError->myName = COMPERR_SLM_EXCEPTION; _computeError->myComment = S_ex.what(); } - catch ( std::bad_alloc& exc ) { - if ( _computeError ) { - _computeError->myName = COMPERR_MEMORY_PB; - _computeError->myComment = exc.what(); - } - throw exc; - } catch ( std::exception& exc ) { if ( !_computeError ) _computeError = SMESH_ComputeError::New(); _computeError->myName = COMPERR_STD_EXCEPTION; @@ -1432,28 +1396,24 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else ret = false; } - if ( ret && _computeError && !_computeError->IsOK() ) { - ret = false; - } if (ret && !_alwaysComputed) { // check if anything was built ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() )); } - if (!ret) + bool isComputeErrorSet = !CheckComputeError( algo, shape ); + if (!ret && !isComputeErrorSet) { // Set _computeError if ( !_computeError ) _computeError = SMESH_ComputeError::New(); if ( _computeError->IsOK() ) _computeError->myName = COMPERR_ALGO_FAILED; + _computeState = FAILED_TO_COMPUTE; } - else + if (ret) { _computeError.reset(); - //UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED } - //if ( !algo->NeedDescretBoundary() ) - // UpdateSubMeshState( ret ? COMPUTE_OK : FAILED_TO_COMPUTE ); - CheckComputeError( algo, shape ); + UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED } break; case CLEAN: @@ -1596,62 +1556,77 @@ bool SMESH_subMesh::ComputeStateEngine(int event) /*! * \brief Update compute_state by _computeError and send proper events to * dependent submeshes + * \retval bool - true if _computeError is NOT set */ //======================================================================= bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape) { - bool noErrors = ( !_computeError || _computeError->IsOK() ); - if ( !noErrors ) + bool noErrors = true; + + if ( !theShape.IsNull() ) + { + // Check state of submeshes + if ( !theAlgo->NeedDescretBoundary()) + { + SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); + while ( smIt->more() ) + if ( !smIt->next()->CheckComputeError( theAlgo )) + noErrors = false; + } + + // Check state of neighbours + if ( !theAlgo->OnlyUnaryInput() && + theShape.ShapeType() == TopAbs_COMPOUND && + !theShape.IsSame( _subShape )) + { + for (TopoDS_Iterator subIt( theShape ); subIt.More(); subIt.Next()) { + SMESH_subMesh* sm = _father->GetSubMesh( subIt.Value() ); + if ( sm != this ) { + if ( !sm->CheckComputeError( theAlgo )) + noErrors = false; + UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED + } + } + } + } { - if ( !_computeError->myAlgo ) - _computeError->myAlgo = theAlgo; - - // Show error - SMESH_Comment text; - text << theAlgo->GetName() << " failed on subshape " << _Id << " with error "; - if (_computeError->IsCommon() ) - text << _computeError->CommonName(); + // Check my state + if ( !_computeError || _computeError->IsOK() ) + { + _computeState = COMPUTE_OK; + } else - text << _computeError->myName; - if ( _computeError->myComment.size() > 0 ) - text << " \"" << _computeError->myComment << "\""; + { + if ( !_computeError->myAlgo ) + _computeError->myAlgo = theAlgo; + + // Show error + SMESH_Comment text; + text << theAlgo->GetName() << " failed on subshape #" << _Id << " with error "; + if (_computeError->IsCommon() ) + text << _computeError->CommonName(); + else + text << _computeError->myName; + if ( _computeError->myComment.size() > 0 ) + text << " \"" << _computeError->myComment << "\""; #ifdef _DEBUG_ - cout << text << endl; - // Show vertices location of a failed shape - cout << "Subshape vertices (first 10):" << endl; - TopTools_IndexedMapOfShape vMap; - TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap ); - for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) { - gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) ))); - cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl; - } + cout << text << endl; + // Show vertices location of a failed shape + TopTools_IndexedMapOfShape vMap; + TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap ); + cout << "Subshape vertices " << ( vMap.Extent()>10 ? "(first 10):" : ":") << endl; + for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) { + gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) ))); + cout << "#" << _father->GetMeshDS()->ShapeToIndex( vMap( iv )) << " "; + cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl; + } #else - INFOS( text ); + INFOS( text ); #endif - _computeState = FAILED_TO_COMPUTE; - } - else - { - _computeState = COMPUTE_OK; - UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED - } - // Check state of submeshes - if ( !theAlgo->NeedDescretBoundary() ) - { - SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); - while ( smIt->more() ) - if ( !smIt->next()->CheckComputeError( theAlgo )) - noErrors = false; - } - if ( !theAlgo->OnlyUnaryInput() && !theShape.IsNull() && - theShape.ShapeType() == TopAbs_COMPOUND ) - { - for (TopoDS_Iterator subIt( theShape ); subIt.More(); subIt.Next()) { - SMESH_subMesh* sm = _father->GetSubMesh( subIt.Value() ); - if ( sm != this && !sm->CheckComputeError( theAlgo )) - noErrors = false; + _computeState = FAILED_TO_COMPUTE; + noErrors = false; } } return noErrors; @@ -1950,8 +1925,9 @@ void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData* map< EventListener*, EventListenerData* >::iterator l_d = myEventListeners.find( listener ); if ( l_d != myEventListeners.end() ) { - if ( l_d->second && l_d->second->IsDeletable() ) - delete l_d->second; + EventListenerData* curData = l_d->second; + if ( curData && curData != data && curData->IsDeletable() ) + delete curData; l_d->second = data; } else @@ -2052,13 +2028,17 @@ void SMESH_subMeshEventListener::ProcessEvent(const int event, eventType == SMESH_subMesh::COMPUTE_EVENT) { ASSERT( data->mySubMeshes.front() != subMesh ); + list::iterator smIt = data->mySubMeshes.begin(); + list::iterator smEnd = data->mySubMeshes.end(); switch ( event ) { case SMESH_subMesh::CLEAN: - data->mySubMeshes.front()->ComputeStateEngine( event ); + for ( ; smIt != smEnd; ++ smIt) + (*smIt)->ComputeStateEngine( event ); break; case SMESH_subMesh::COMPUTE: if ( subMesh->GetComputeState() == SMESH_subMesh::COMPUTE_OK ) - data->mySubMeshes.front()->ComputeStateEngine( SMESH_subMesh::SUBMESH_COMPUTED ); + for ( ; smIt != smEnd; ++ smIt) + (*smIt)->ComputeStateEngine( SMESH_subMesh::SUBMESH_COMPUTED ); break; default:; }