X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Gen.cxx;h=44e5a46d39a1894f36380c7cf106025a4a2cb59b;hb=71b66afd043b8178caac7b4d53553407cda59987;hp=df6424696a236f50695c1beee8e40a813d8b2d99;hpb=7f64a1c94a6ee08c4076021bfc2f7b7415df628e;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index df6424696..44e5a46d3 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -43,12 +43,18 @@ #include "Utils_ExceptHandlers.hxx" #include -#include #include "memoire.h" +#ifdef WNT + #include +#endif + using namespace std; +//#include + + //============================================================================= /*! * Constructor @@ -57,17 +63,16 @@ using namespace std; SMESH_Gen::SMESH_Gen() { - MESSAGE("SMESH_Gen::SMESH_Gen"); - _localId = 0; - _hypId = 0; - _segmentation = _nbSegments = 10; - SMDS_Mesh::_meshList.clear(); - MESSAGE(SMDS_Mesh::_meshList.size()); - _counters = new counters(100); -#ifdef WITH_SMESH_CANCEL_COMPUTE - _compute_canceled = false; - _sm_current = NULL; -#endif + MESSAGE("SMESH_Gen::SMESH_Gen"); + _localId = 0; + _hypId = 0; + _segmentation = _nbSegments = 10; + SMDS_Mesh::_meshList.clear(); + MESSAGE(SMDS_Mesh::_meshList.size()); + //_counters = new counters(100); + _compute_canceled = false; + _sm_current = NULL; + //vtkDebugLeaks::SetExitError(0); } //============================================================================= @@ -79,6 +84,12 @@ SMESH_Gen::SMESH_Gen() SMESH_Gen::~SMESH_Gen() { MESSAGE("SMESH_Gen::~SMESH_Gen"); + std::map < int, StudyContextStruct * >::iterator i_sc = _mapStudyContext.begin(); + for ( ; i_sc != _mapStudyContext.end(); ++i_sc ) + { + delete i_sc->second->myDocument; + delete i_sc->second; + } } //============================================================================= @@ -132,6 +143,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const int globalAlgoDim = 100; SMESH_subMeshIteratorPtr smIt; + SMESH_subMesh::compute_event computeEvent; + if ( !anUpward && aShape.IsSame( aMesh.GetShapeToMesh() )) + computeEvent = SMESH_subMesh::COMPUTE; + else + computeEvent = SMESH_subMesh::COMPUTE_SUBMESH; if ( anUpward ) // is called from below code here { @@ -151,7 +167,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // check for preview dimension limitations if ( aShapesId && GetShapeDim( aShType ) > (int)aDim ) { - // clear compute state to not show previous compute errors + // clear compute state not to show previous compute errors // if preview invoked less dimension less than previous smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); continue; @@ -159,15 +175,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { -#ifdef WITH_SMESH_CANCEL_COMPUTE if (_compute_canceled) return false; _sm_current = smToCompute; -#endif - smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE ); -#ifdef WITH_SMESH_CANCEL_COMPUTE + smToCompute->ComputeStateEngine( computeEvent ); _sm_current = NULL; -#endif } // we check all the submeshes here and detect if any of them failed to compute @@ -245,15 +257,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } else { -#ifdef WITH_SMESH_CANCEL_COMPUTE if (_compute_canceled) return false; _sm_current = smToCompute; -#endif - smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE ); -#ifdef WITH_SMESH_CANCEL_COMPUTE + smToCompute->ComputeStateEngine( computeEvent ); _sm_current = NULL; -#endif if ( aShapesId ) aShapesId->insert( smToCompute->GetId() ); } @@ -308,6 +316,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh )); if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) { + if ( ! subAlgo->NeedDiscreteBoundary() ) continue; SMESH_Hypothesis::Hypothesis_Status status; if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status )) // mesh a lower smToCompute starting from vertices @@ -328,15 +337,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, if ( aShapesId && GetShapeDim( aShType ) > (int)aDim ) continue; -#ifdef WITH_SMESH_CANCEL_COMPUTE if (_compute_canceled) return false; _sm_current = sm; -#endif - sm->ComputeStateEngine( SMESH_subMesh::COMPUTE ); -#ifdef WITH_SMESH_CANCEL_COMPUTE + sm->ComputeStateEngine( computeEvent ); _sm_current = NULL; -#endif if ( aShapesId ) aShapesId->insert( sm->GetId() ); } @@ -351,31 +356,19 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, MEMOSTAT; SMESHDS_Mesh *myMesh = aMesh.GetMeshDS(); - myMesh->adjustStructure(); MESSAGE("*** compactMesh after compute"); myMesh->compactMesh(); - //myMesh->adjustStructure(); - list listind = myMesh->SubMeshIndices(); - list::iterator it = listind.begin(); - int total = 0; - for(; it != listind.end(); ++it) - { - ::SMESHDS_SubMesh *subMesh = myMesh->MeshElements(*it); - total += subMesh->getSize(); - } - MESSAGE("total elements and nodes in submesh sets:" << total); - MESSAGE("Number of node objects " << SMDS_MeshNode::nbNodes); - MESSAGE("Number of cell objects " << SMDS_MeshCell::nbCells); - //myMesh->dumpGrid(); - //aMesh.GetMeshDS()->Modified(); // fix quadratic mesh by bending iternal links near concave boundary if ( aShape.IsSame( aMesh.GetShapeToMesh() ) && - !aShapesId ) // not preview + !aShapesId && // not preview + ret ) // everything is OK { SMESH_MesherHelper aHelper( aMesh ); if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR ) - aHelper.FixQuadraticElements(); + { + aHelper.FixQuadraticElements( sm->GetComputeError() ); + } } return ret; } @@ -520,6 +513,7 @@ bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh, .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh )); if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) { + if ( ! subAlgo->NeedDiscreteBoundary() ) continue; SMESH_Hypothesis::Hypothesis_Status status; if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status )) // mesh a lower smToCompute starting from vertices @@ -583,18 +577,24 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh, if ( aLocIgnoAlgo ) // algo is hidden by a local algo of upper dim { + theErrors.push_back( SMESH_Gen::TAlgoStateError() ); + theErrors.back().Set( SMESH_Hypothesis::HYP_HIDDEN_ALGO, algo, false ); INFOS( "Local <" << algo->GetName() << "> is hidden by local <" << aLocIgnoAlgo->GetName() << ">"); } else { - bool isGlobal = (aMesh.IsMainShape( aSubMesh->GetSubShape() )); - int dim = algo->GetDim(); + bool isGlobal = (aMesh.IsMainShape( aSubMesh->GetSubShape() )); + int dim = algo->GetDim(); int aMaxGlobIgnoDim = ( aGlobIgnoAlgo ? aGlobIgnoAlgo->GetDim() : -1 ); + bool isNeededDim = ( aGlobIgnoAlgo ? aGlobIgnoAlgo->NeedLowerHyps( dim ) : false ); - if ( dim < aMaxGlobIgnoDim ) + if (( dim < aMaxGlobIgnoDim && !isNeededDim ) && + ( isGlobal || !aGlobIgnoAlgo->SupportSubmeshes() )) { // algo is hidden by a global algo + theErrors.push_back( SMESH_Gen::TAlgoStateError() ); + theErrors.back().Set( SMESH_Hypothesis::HYP_HIDDEN_ALGO, algo, true ); INFOS( ( isGlobal ? "Global" : "Local" ) << " <" << algo->GetName() << "> is hidden by global <" << aGlobIgnoAlgo->GetName() << ">"); @@ -646,7 +646,15 @@ static bool checkMissing(SMESH_Gen* aGen, set& aCheckedMap, list< SMESH_Gen::TAlgoStateError > & theErrors) { - if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX) + switch ( aSubMesh->GetSubShape().ShapeType() ) + { + case TopAbs_EDGE: + case TopAbs_FACE: + case TopAbs_SOLID: break; // check this submesh, it can be meshed + default: + return true; // not meshable submesh + } + if ( aCheckedMap.count( aSubMesh )) return true; //MESSAGE("=====checkMissing"); @@ -673,7 +681,7 @@ static bool checkMissing(SMESH_Gen* aGen, } case SMESH_subMesh::MISSING_HYP: { // notify if an algo missing hyp is attached to aSubMesh - algo = aGen->GetAlgo( aMesh, aSubMesh->GetSubShape() ); + algo = aSubMesh->GetAlgo(); ASSERT( algo ); bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh ); if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ]) @@ -702,8 +710,15 @@ static bool checkMissing(SMESH_Gen* aGen, break; } case SMESH_subMesh::HYP_OK: - algo = aGen->GetAlgo( aMesh, aSubMesh->GetSubShape() ); + algo = aSubMesh->GetAlgo(); ret = true; + if (!algo->NeedDiscreteBoundary()) + { + SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false, + /*complexShapeFirst=*/false); + while ( itsub->more() ) + aCheckedMap.insert( itsub->next() ); + } break; default: ASSERT(0); } @@ -717,12 +732,11 @@ static bool checkMissing(SMESH_Gen* aGen, { bool checkNoAlgo2 = ( algo->NeedDiscreteBoundary() ); SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false, - /*complexShapeFirst=*/false); + /*complexShapeFirst=*/true); while ( itsub->more() ) { // sub-meshes should not be checked further more SMESH_subMesh* sm = itsub->next(); - aCheckedMap.insert( sm ); if (isTopLocalAlgo) { @@ -736,6 +750,7 @@ static bool checkMissing(SMESH_Gen* aGen, checkNoAlgo2 = false; } } + aCheckedMap.insert( sm ); } } return ret; @@ -769,9 +784,9 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh, bool ret = true; bool hasAlgo = false; - SMESH_subMesh* sm = theMesh.GetSubMesh(theShape); + SMESH_subMesh* sm = theMesh.GetSubMesh(theShape); const SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); - TopoDS_Shape mainShape = meshDS->ShapeToMesh(); + TopoDS_Shape mainShape = meshDS->ShapeToMesh(); // ----------------- // get global algos @@ -809,7 +824,8 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh, for (dim = 3; dim > 0; dim--) { if (aGlobAlgoArr[ dim ] && - !aGlobAlgoArr[ dim ]->NeedDiscreteBoundary()) + !aGlobAlgoArr[ dim ]->NeedDiscreteBoundary() /*&& + !aGlobAlgoArr[ dim ]->SupportSubmeshes()*/ ) { aGlobIgnoAlgo = aGlobAlgoArr[ dim ]; break; @@ -866,14 +882,13 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh, if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX) break; - if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked - if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim, - globalChecked, checkNoAlgo, aCheckedSubs, theErrors)) - { - ret = false; - if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO ) - checkNoAlgo = false; - } + if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim, + globalChecked, checkNoAlgo, aCheckedSubs, theErrors)) + { + ret = false; + if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO ) + checkNoAlgo = false; + } } if ( !hasAlgo ) { @@ -974,99 +989,6 @@ std::vector< std::string > SMESH_Gen::GetPluginXMLPaths() return xmlPaths; } -//======================================================================= -namespace // Access to type of input and output of an algorithm -//======================================================================= -{ - struct AlgoData - { - int _dim; - set _inElemTypes; // acceptable types of input mesh element - set _outElemTypes; // produced types of mesh elements - - bool IsCompatible( const AlgoData& algo2 ) const - { - if ( _dim > algo2._dim ) return algo2.IsCompatible( *this ); - // algo2 is of highter dimension - if ( _outElemTypes.empty() || algo2._inElemTypes.empty() ) - return false; - bool compatible = true; - set::const_iterator myOutType = _outElemTypes.begin(); - for ( ; myOutType != _outElemTypes.end() && compatible; ++myOutType ) - compatible = algo2._inElemTypes.count( *myOutType ); - return compatible; - } - }; - - //================================================================================ - /*! - * \brief Return AlgoData of the algorithm - */ - //================================================================================ - - const AlgoData& getAlgoData( const SMESH_Algo* algo ) - { - static map< string, AlgoData > theDataByName; - if ( theDataByName.empty() ) - { - // Read Plugin.xml files - vector< string > xmlPaths = SMESH_Gen::GetPluginXMLPaths(); - LDOMParser xmlParser; - for ( size_t i = 0; i < xmlPaths.size(); ++i ) - { - bool error = xmlParser.parse( xmlPaths[i].c_str() ); - if ( error ) - { - TCollection_AsciiString data; - INFOS( xmlParser.GetError(data) ); - continue; - } - // - // - LDOM_Document xmlDoc = xmlParser.getDocument(); - LDOM_NodeList algoNodeList = xmlDoc.getElementsByTagName( "algorithm" ); - for ( int i = 0; i < algoNodeList.getLength(); ++i ) - { - LDOM_Node algoNode = algoNodeList.item( i ); - LDOM_Element& algoElem = (LDOM_Element&) algoNode; - TCollection_AsciiString algoType = algoElem.getAttribute("type"); - TCollection_AsciiString input = algoElem.getAttribute("input"); - TCollection_AsciiString output = algoElem.getAttribute("output"); - TCollection_AsciiString dim = algoElem.getAttribute("dim"); - AlgoData & data = theDataByName[ algoType.ToCString() ]; - data._dim = dim.IntegerValue(); - for ( int isInput = 0; isInput < 2; ++isInput ) - { - TCollection_AsciiString& typeStr = isInput ? input : output; - set& typeSet = isInput ? data._inElemTypes : data._outElemTypes; - int beg = 1, end; - while ( beg <= typeStr.Length() ) - { - while ( beg < typeStr.Length() && !isalpha( typeStr.Value( beg ) )) - ++beg; - end = beg; - while ( end < typeStr.Length() && isalpha( typeStr.Value( end + 1 ) )) - ++end; - if ( end > beg ) - { - TCollection_AsciiString typeName = typeStr.SubString( beg, end ); - if ( typeName == "EDGE" ) typeSet.insert( SMDSGeom_EDGE ); - else if ( typeName == "TRIA" ) typeSet.insert( SMDSGeom_TRIANGLE ); - else if ( typeName == "QUAD" ) typeSet.insert( SMDSGeom_QUADRANGLE ); - } - beg = end + 1; - } - } - } - } - } - return theDataByName[ algo->GetName() ]; - } -} - //============================================================================= /*! * Finds algo to mesh a shape. Optionally returns a shape the found algo is bound to @@ -1080,6 +1002,8 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); filter.And( filter.IsApplicableTo( aShape )); + typedef SMESH_Algo::Features AlgoData; + TopoDS_Shape assignedToShape; SMESH_Algo* algo = (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape ); @@ -1098,9 +1022,11 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, TopoDS_Shape assignedToShape2; SMESH_Algo* algo2 = (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape2 ); - if ( algo2 && - assignedToShape2.ShapeType() == assignedToShape.ShapeType() && - aMesh.IsOrderOK( aMesh.GetSubMesh( assignedToShape2 ), + if ( algo2 && // algo found + !assignedToShape2.IsSame( aMesh.GetShapeToMesh() ) && // algo is local + ( SMESH_MesherHelper::GetGroupType( assignedToShape2 ) == // algo of the same level + SMESH_MesherHelper::GetGroupType( assignedToShape )) && + aMesh.IsOrderOK( aMesh.GetSubMesh( assignedToShape2 ), // no forced order aMesh.GetSubMesh( assignedToShape ))) { // get algos on the adjacent SOLIDs @@ -1112,15 +1038,15 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, if ( SMESH_Algo* algo3D = (SMESH_Algo*) aMesh.GetHypothesis( *solid, filter, true )) { algos3D.push_back( algo3D ); - filter.AndNot( filter.Is( algo3D )); + filter.AndNot( filter.HasName( algo3D->GetName() )); } // check compatibility of algos if ( algos3D.size() > 1 ) { - const AlgoData& algoData = getAlgoData( algo ); - const AlgoData& algoData2 = getAlgoData( algo2 ); - const AlgoData& algoData3d0 = getAlgoData( algos3D[0] ); - const AlgoData& algoData3d1 = getAlgoData( algos3D[1] ); + const AlgoData& algoData = algo->SMESH_Algo::GetFeatures(); + const AlgoData& algoData2 = algo2->SMESH_Algo::GetFeatures(); + const AlgoData& algoData3d0 = algos3D[0]->SMESH_Algo::GetFeatures(); + const AlgoData& algoData3d1 = algos3D[1]->SMESH_Algo::GetFeatures(); if (( algoData2.IsCompatible( algoData3d0 ) && algoData2.IsCompatible( algoData3d1 )) &&