Version: 6.3.1

src/SMESH/SMESH_Gen.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH SMESH : implementaion of SMESH idl descriptions
00024 //  File   : SMESH_Gen.cxx
00025 //  Author : Paul RASCLE, EDF
00026 //  Module : SMESH
00027 //
00028 
00029 //#define CHRONODEF
00030 
00031 #include "SMESH_Gen.hxx"
00032 
00033 #include "SMDS_Mesh.hxx"
00034 #include "SMDS_MeshElement.hxx"
00035 #include "SMDS_MeshNode.hxx"
00036 #include "SMESHDS_Document.hxx"
00037 #include "SMESH_HypoFilter.hxx"
00038 #include "SMESH_MesherHelper.hxx"
00039 #include "SMESH_subMesh.hxx"
00040 
00041 #include "utilities.h"
00042 #include "OpUtil.hxx"
00043 #include "Utils_ExceptHandlers.hxx"
00044 
00045 #include <TopoDS_Iterator.hxx>
00046 
00047 #include "memoire.h"
00048 
00049 using namespace std;
00050 
00051 //=============================================================================
00055 //=============================================================================
00056 
00057 SMESH_Gen::SMESH_Gen()
00058 {
00059         MESSAGE("SMESH_Gen::SMESH_Gen");
00060         _localId = 0;
00061         _hypId = 0;
00062         _segmentation = _nbSegments = 10;
00063         SMDS_Mesh::_meshList.clear();
00064         MESSAGE(SMDS_Mesh::_meshList.size());
00065         _counters = new counters(100);
00066 #ifdef WITH_SMESH_CANCEL_COMPUTE
00067         _compute_canceled = false;
00068         _sm_current = NULL;
00069 #endif
00070 }
00071 
00072 //=============================================================================
00076 //=============================================================================
00077 
00078 SMESH_Gen::~SMESH_Gen()
00079 {
00080   MESSAGE("SMESH_Gen::~SMESH_Gen");
00081 }
00082 
00083 //=============================================================================
00088 //=============================================================================
00089 
00090 SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
00091   throw(SALOME_Exception)
00092 {
00093   Unexpect aCatch(SalomeException);
00094   MESSAGE("SMESH_Gen::CreateMesh");
00095 
00096   // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
00097   StudyContextStruct *aStudyContext = GetStudyContext(theStudyId);
00098 
00099   // create a new SMESH_mesh object
00100   SMESH_Mesh *aMesh = new SMESH_Mesh(_localId++,
00101                                      theStudyId,
00102                                      this,
00103                                      theIsEmbeddedMode,
00104                                      aStudyContext->myDocument);
00105   aStudyContext->mapMesh[_localId] = aMesh;
00106 
00107   return aMesh;
00108 }
00109 
00110 //=============================================================================
00114 //=============================================================================
00115 
00116 bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
00117                         const TopoDS_Shape &  aShape,
00118                         const bool            anUpward,
00119                         const ::MeshDimension aDim,
00120                         TSetOfInt*            aShapesId)
00121 {
00122   MESSAGE("SMESH_Gen::Compute");
00123   MEMOSTAT;
00124 
00125   bool ret = true;
00126 
00127   SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
00128 
00129   const bool includeSelf = true;
00130   const bool complexShapeFirst = true;
00131 
00132   SMESH_subMeshIteratorPtr smIt;
00133 
00134   if ( anUpward ) // is called from below code here
00135   {
00136     // -----------------------------------------------
00137     // mesh all the subshapes starting from vertices
00138     // -----------------------------------------------
00139     smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
00140     while ( smIt->more() )
00141     {
00142       SMESH_subMesh* smToCompute = smIt->next();
00143 
00144       // do not mesh vertices of a pseudo shape
00145       const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
00146       if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
00147         continue;
00148 
00149       // check for preview dimension limitations
00150       if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
00151       {
00152         // clear compute state to not show previous compute errors
00153         //  if preview invoked less dimension less than previous
00154         smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
00155         continue;
00156       }
00157 
00158       if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
00159       {
00160 #ifdef WITH_SMESH_CANCEL_COMPUTE
00161         if (_compute_canceled)
00162           return false;
00163         _sm_current = smToCompute;
00164 #endif
00165         smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
00166 #ifdef WITH_SMESH_CANCEL_COMPUTE
00167         _sm_current = NULL;
00168 #endif
00169       }
00170 
00171       // we check all the submeshes here and detect if any of them failed to compute
00172       if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
00173         ret = false;
00174       else if ( aShapesId )
00175         aShapesId->insert( smToCompute->GetId() );
00176     }
00177     //aMesh.GetMeshDS()->Modified();
00178     return ret;
00179   }
00180   else
00181   {
00182     // -----------------------------------------------------------------
00183     // apply algos that DO NOT require descretized boundaries and DO NOT
00184     // support submeshes, starting from the most complex shapes
00185     // and collect submeshes with algos that DO support submeshes
00186     // -----------------------------------------------------------------
00187     list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
00188 
00189     // map to sort sm with same dim algos according to dim of
00190     // the shape the algo assigned to (issue 0021217)
00191     multimap< int, SMESH_subMesh* > shDim2sm;
00192     multimap< int, SMESH_subMesh* >::reverse_iterator shDim2smIt;
00193     TopoDS_Shape algoShape;
00194     int prevShapeDim = -1;
00195 
00196     smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
00197     while ( smIt->more() )
00198     {
00199       SMESH_subMesh* smToCompute = smIt->next();
00200       if ( smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE )
00201         continue;
00202 
00203       const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
00204       int aShapeDim = GetShapeDim( aSubShape );
00205       if ( aShapeDim < 1 ) break;
00206       
00207       // check for preview dimension limitations
00208       if ( aShapesId && aShapeDim > (int)aDim )
00209         continue;
00210 
00211       SMESH_Algo* algo = GetAlgo( aMesh, aSubShape, &algoShape );
00212       if ( algo && !algo->NeedDescretBoundary() )
00213       {
00214         if ( algo->SupportSubmeshes() )
00215         {
00216           // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
00217           if ( prevShapeDim != aShapeDim )
00218           {
00219             prevShapeDim = aShapeDim;
00220             for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
00221               smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
00222             shDim2sm.clear();
00223           }
00224           // add smToCompute to shDim2sm map
00225           aShapeDim = GetShapeDim( algoShape );
00226           if ( algoShape.ShapeType() == TopAbs_COMPOUND )
00227           {
00228             TopoDS_Iterator it( algoShape );
00229             aShapeDim += GetShapeDim( it.Value() );
00230           }
00231           shDim2sm.insert( make_pair( aShapeDim, smToCompute ));
00232         }
00233         else
00234         {
00235 #ifdef WITH_SMESH_CANCEL_COMPUTE
00236           if (_compute_canceled)
00237             return false;
00238           _sm_current = smToCompute;
00239 #endif
00240           smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
00241 #ifdef WITH_SMESH_CANCEL_COMPUTE
00242           _sm_current = NULL;
00243 #endif
00244           if ( aShapesId )
00245             aShapesId->insert( smToCompute->GetId() );
00246         }
00247       }
00248     }
00249     // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
00250     for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
00251       smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
00252 
00253     // ------------------------------------------------------------
00254     // sort list of submeshes according to mesh order
00255     // ------------------------------------------------------------
00256     aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
00257 
00258     // ------------------------------------------------------------
00259     // compute submeshes under shapes with algos that DO NOT require
00260     // descretized boundaries and DO support submeshes
00261     // ------------------------------------------------------------
00262     list< SMESH_subMesh* >::iterator subIt, subEnd;
00263     subIt  = smWithAlgoSupportingSubmeshes.begin();
00264     subEnd = smWithAlgoSupportingSubmeshes.end();
00265     // start from lower shapes
00266     for ( ; subIt != subEnd; ++subIt )
00267     {
00268       sm = *subIt;
00269 
00270       // get a shape the algo is assigned to
00271       if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
00272         continue; // strange...
00273 
00274       // look for more local algos
00275       smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
00276       while ( smIt->more() )
00277       {
00278         SMESH_subMesh* smToCompute = smIt->next();
00279 
00280         const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
00281         const int aShapeDim = GetShapeDim( aSubShape );
00282         //if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
00283         if ( aShapeDim < 1 ) continue;
00284 
00285         // check for preview dimension limitations
00286         if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
00287           continue;
00288         
00289         SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
00290         filter
00291           .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
00292           .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
00293 
00294         if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
00295           SMESH_Hypothesis::Hypothesis_Status status;
00296           if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
00297             // mesh a lower smToCompute starting from vertices
00298             Compute( aMesh, aSubShape, /*anUpward=*/true, aDim, aShapesId );
00299         }
00300       }
00301     }
00302     // ----------------------------------------------------------
00303     // apply the algos that do not require descretized boundaries
00304     // ----------------------------------------------------------
00305     for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
00306     {
00307       sm = *subIt;
00308       if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
00309       {
00310         const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
00311         // check for preview dimension limitations
00312         if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
00313           continue;
00314 
00315 #ifdef WITH_SMESH_CANCEL_COMPUTE
00316         if (_compute_canceled)
00317           return false;
00318         _sm_current = sm;
00319 #endif
00320         sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
00321 #ifdef WITH_SMESH_CANCEL_COMPUTE
00322         _sm_current = NULL;
00323 #endif
00324         if ( aShapesId )
00325           aShapesId->insert( sm->GetId() );
00326       }
00327     }
00328     // -----------------------------------------------
00329     // mesh the rest subshapes starting from vertices
00330     // -----------------------------------------------
00331     ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId );
00332   }
00333 
00334   MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
00335   MEMOSTAT;
00336 
00337   SMESHDS_Mesh *myMesh = aMesh.GetMeshDS();
00338   myMesh->adjustStructure();
00339   MESSAGE("*** compactMesh after compute");
00340   myMesh->compactMesh();
00341   //myMesh->adjustStructure();
00342   list<int> listind = myMesh->SubMeshIndices();
00343   list<int>::iterator it = listind.begin();
00344   int total = 0;
00345   for(; it != listind.end(); ++it)
00346     {
00347       ::SMESHDS_SubMesh *subMesh = myMesh->MeshElements(*it);
00348       total +=  subMesh->getSize();
00349     }
00350   MESSAGE("total elements and nodes in submesh sets:" << total);
00351   MESSAGE("Number of node objects " << SMDS_MeshNode::nbNodes);
00352   MESSAGE("Number of cell objects " << SMDS_MeshCell::nbCells);
00353   //myMesh->dumpGrid();
00354   //aMesh.GetMeshDS()->Modified();
00355 
00356   // fix quadratic mesh by bending iternal links near concave boundary
00357   if ( aShape.IsSame( aMesh.GetShapeToMesh() ) &&
00358        !aShapesId ) // not preview
00359   {
00360     SMESH_MesherHelper aHelper( aMesh );
00361     if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR )
00362       aHelper.FixQuadraticElements();
00363   }
00364   return ret;
00365 }
00366 
00367 
00368 #ifdef WITH_SMESH_CANCEL_COMPUTE
00369 //=============================================================================
00373 //=============================================================================
00374 void SMESH_Gen::PrepareCompute(SMESH_Mesh &          aMesh,
00375                                const TopoDS_Shape &  aShape)
00376 {
00377   _compute_canceled = false;
00378   _sm_current = NULL;
00379 }
00380 //=============================================================================
00384 //=============================================================================
00385 void SMESH_Gen::CancelCompute(SMESH_Mesh &          aMesh,
00386                               const TopoDS_Shape &  aShape)
00387 {
00388   _compute_canceled = true;
00389   if(_sm_current)
00390     {
00391       _sm_current->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
00392     }
00393 }
00394 #endif
00395 
00396 //=============================================================================
00400 //=============================================================================
00401 
00402 bool SMESH_Gen::Evaluate(SMESH_Mesh &          aMesh,
00403                          const TopoDS_Shape &  aShape,
00404                          MapShapeNbElems&      aResMap,
00405                          const bool            anUpward,
00406                          TSetOfInt*            aShapesId)
00407 {
00408   MESSAGE("SMESH_Gen::Evaluate");
00409 
00410   bool ret = true;
00411 
00412   SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
00413 
00414   const bool includeSelf = true;
00415   const bool complexShapeFirst = true;
00416   SMESH_subMeshIteratorPtr smIt;
00417 
00418   if ( anUpward ) { // is called from below code here
00419     // -----------------------------------------------
00420     // mesh all the subshapes starting from vertices
00421     // -----------------------------------------------
00422     smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
00423     while ( smIt->more() ) {
00424       SMESH_subMesh* smToCompute = smIt->next();
00425 
00426       // do not mesh vertices of a pseudo shape
00427       const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
00428       //if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
00429       //  continue;
00430       if ( !aMesh.HasShapeToMesh() ) {
00431         if( aShType == TopAbs_VERTEX || aShType == TopAbs_WIRE ||
00432             aShType == TopAbs_SHELL )
00433           continue;
00434       }
00435 
00436       smToCompute->Evaluate(aResMap);
00437       if( aShapesId )
00438         aShapesId->insert( smToCompute->GetId() );
00439     }
00440     return ret;
00441   }
00442   else {
00443     // -----------------------------------------------------------------
00444     // apply algos that DO NOT require descretized boundaries and DO NOT
00445     // support submeshes, starting from the most complex shapes
00446     // and collect submeshes with algos that DO support submeshes
00447     // -----------------------------------------------------------------
00448     list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
00449     smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
00450     while ( smIt->more() ) {
00451       SMESH_subMesh* smToCompute = smIt->next();
00452       const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
00453       const int aShapeDim = GetShapeDim( aSubShape );
00454       if ( aShapeDim < 1 ) break;
00455       
00456       SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
00457       if ( algo && !algo->NeedDescretBoundary() ) {
00458         if ( algo->SupportSubmeshes() ) {
00459           smWithAlgoSupportingSubmeshes.push_front( smToCompute );
00460         }
00461         else {
00462           smToCompute->Evaluate(aResMap);
00463           if ( aShapesId )
00464             aShapesId->insert( smToCompute->GetId() );
00465         }
00466       }
00467     }
00468 
00469     // ------------------------------------------------------------
00470     // sort list of meshes according to mesh order
00471     // ------------------------------------------------------------
00472     aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
00473 
00474     // ------------------------------------------------------------
00475     // compute submeshes under shapes with algos that DO NOT require
00476     // descretized boundaries and DO support submeshes
00477     // ------------------------------------------------------------
00478     list< SMESH_subMesh* >::iterator subIt, subEnd;
00479     subIt  = smWithAlgoSupportingSubmeshes.begin();
00480     subEnd = smWithAlgoSupportingSubmeshes.end();
00481     // start from lower shapes
00482     for ( ; subIt != subEnd; ++subIt ) {
00483       sm = *subIt;
00484 
00485       // get a shape the algo is assigned to
00486       TopoDS_Shape algoShape;
00487       if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
00488         continue; // strange...
00489 
00490       // look for more local algos
00491       smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
00492       while ( smIt->more() ) {
00493         SMESH_subMesh* smToCompute = smIt->next();
00494 
00495         const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
00496         const int aShapeDim = GetShapeDim( aSubShape );
00497         if ( aShapeDim < 1 ) continue;
00498 
00499         //const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
00500 
00501         SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
00502         filter
00503           .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
00504           .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
00505 
00506         if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
00507           SMESH_Hypothesis::Hypothesis_Status status;
00508           if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
00509             // mesh a lower smToCompute starting from vertices
00510             Evaluate( aMesh, aSubShape, aResMap, /*anUpward=*/true, aShapesId );
00511         }
00512       }
00513     }
00514     // ----------------------------------------------------------
00515     // apply the algos that do not require descretized boundaries
00516     // ----------------------------------------------------------
00517     for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
00518     {
00519       sm = *subIt;
00520       sm->Evaluate(aResMap);
00521       if ( aShapesId )
00522         aShapesId->insert( sm->GetId() );
00523     }
00524 
00525     // -----------------------------------------------
00526     // mesh the rest subshapes starting from vertices
00527     // -----------------------------------------------
00528     ret = Evaluate( aMesh, aShape, aResMap, /*anUpward=*/true, aShapesId );
00529   }
00530 
00531   MESSAGE( "VSR - SMESH_Gen::Evaluate() finished, OK = " << ret);
00532   return ret;
00533 }
00534 
00535 
00536 //=======================================================================
00537 //function : checkConformIgnoredAlgos
00538 //purpose  :
00539 //=======================================================================
00540 
00541 static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
00542                                      SMESH_subMesh*            aSubMesh,
00543                                      const SMESH_Algo*         aGlobIgnoAlgo,
00544                                      const SMESH_Algo*         aLocIgnoAlgo,
00545                                      bool &                    checkConform,
00546                                      set<SMESH_subMesh*>&      aCheckedMap,
00547                                      list< SMESH_Gen::TAlgoStateError > & theErrors)
00548 {
00549   ASSERT( aSubMesh );
00550   if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX)
00551     return true;
00552 
00553 
00554   bool ret = true;
00555 
00556   const list<const SMESHDS_Hypothesis*>& listHyp =
00557     aMesh.GetMeshDS()->GetHypothesis( aSubMesh->GetSubShape() );
00558   list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
00559   for ( ; it != listHyp.end(); it++)
00560   {
00561     const SMESHDS_Hypothesis * aHyp = *it;
00562     if (aHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
00563       continue;
00564 
00565     const SMESH_Algo* algo = dynamic_cast<const SMESH_Algo*> (aHyp);
00566     ASSERT ( algo );
00567 
00568     if ( aLocIgnoAlgo ) // algo is hidden by a local algo of upper dim
00569     {
00570       INFOS( "Local <" << algo->GetName() << "> is hidden by local <"
00571             << aLocIgnoAlgo->GetName() << ">");
00572     }
00573     else
00574     {
00575       bool isGlobal = (aMesh.IsMainShape( aSubMesh->GetSubShape() ));
00576       int dim = algo->GetDim();
00577       int aMaxGlobIgnoDim = ( aGlobIgnoAlgo ? aGlobIgnoAlgo->GetDim() : -1 );
00578 
00579       if ( dim < aMaxGlobIgnoDim )
00580       {
00581         // algo is hidden by a global algo
00582         INFOS( ( isGlobal ? "Global" : "Local" )
00583               << " <" << algo->GetName() << "> is hidden by global <"
00584               << aGlobIgnoAlgo->GetName() << ">");
00585       }
00586       else if ( !algo->NeedDescretBoundary() && !isGlobal)
00587       {
00588         // local algo is not hidden and hides algos on sub-shapes
00589         if (checkConform && !aSubMesh->IsConform( algo ))
00590         {
00591           ret = false;
00592           checkConform = false; // no more check conformity
00593           INFOS( "ERROR: Local <" << algo->GetName() <<
00594                 "> would produce not conform mesh: "
00595                 "<Not Conform Mesh Allowed> hypotesis is missing");
00596           theErrors.push_back( SMESH_Gen::TAlgoStateError() );
00597           theErrors.back().Set( SMESH_Hypothesis::HYP_NOTCONFORM, algo, false );
00598         }
00599 
00600         // sub-algos will be hidden by a local <algo>
00601         SMESH_subMeshIteratorPtr revItSub =
00602           aSubMesh->getDependsOnIterator( /*includeSelf=*/false, /*complexShapeFirst=*/true);
00603         bool checkConform2 = false;
00604         while ( revItSub->more() )
00605         {
00606           SMESH_subMesh* sm = revItSub->next();
00607           checkConformIgnoredAlgos (aMesh, sm, aGlobIgnoAlgo,
00608                                     algo, checkConform2, aCheckedMap, theErrors);
00609           aCheckedMap.insert( sm );
00610         }
00611       }
00612     }
00613   }
00614 
00615   return ret;
00616 }
00617 
00618 //=======================================================================
00619 //function : checkMissing
00620 //purpose  : notify on missing hypothesis
00621 //           Return false if algo or hipothesis is missing
00622 //=======================================================================
00623 
00624 static bool checkMissing(SMESH_Gen*                aGen,
00625                          SMESH_Mesh&               aMesh,
00626                          SMESH_subMesh*            aSubMesh,
00627                          const int                 aTopAlgoDim,
00628                          bool*                     globalChecked,
00629                          const bool                checkNoAlgo,
00630                          set<SMESH_subMesh*>&      aCheckedMap,
00631                          list< SMESH_Gen::TAlgoStateError > & theErrors)
00632 {
00633   if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX)
00634     return true;
00635 
00636   //MESSAGE("=====checkMissing");
00637 
00638   int ret = true;
00639   SMESH_Algo* algo = 0;
00640 
00641   switch (aSubMesh->GetAlgoState())
00642   {
00643   case SMESH_subMesh::NO_ALGO: {
00644     if (checkNoAlgo)
00645     {
00646       // should there be any algo?
00647       int shapeDim = SMESH_Gen::GetShapeDim( aSubMesh->GetSubShape() );
00648       if (aTopAlgoDim > shapeDim)
00649       {
00650         MESSAGE( "ERROR: " << shapeDim << "D algorithm is missing" );
00651         ret = false;
00652         theErrors.push_back( SMESH_Gen::TAlgoStateError() );
00653         theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, shapeDim, true );
00654       }
00655     }
00656     return ret;
00657   }
00658   case SMESH_subMesh::MISSING_HYP: {
00659     // notify if an algo missing hyp is attached to aSubMesh
00660     algo = aGen->GetAlgo( aMesh, aSubMesh->GetSubShape() );
00661     ASSERT( algo );
00662     bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh );
00663     if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ])
00664     {
00665       TAlgoStateErrorName errName = SMESH_Hypothesis::HYP_MISSING;
00666       SMESH_Hypothesis::Hypothesis_Status status;
00667       algo->CheckHypothesis( aMesh, aSubMesh->GetSubShape(), status );
00668       if ( status == SMESH_Hypothesis::HYP_BAD_PARAMETER ) {
00669         MESSAGE( "ERROR: hypothesis of " << (IsGlobalHypothesis ? "Global " : "Local ")
00670                  << "<" << algo->GetName() << "> has a bad parameter value");
00671         errName = status;
00672       } else if ( status == SMESH_Hypothesis::HYP_BAD_GEOMETRY ) {
00673         MESSAGE( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ")
00674                  << "<" << algo->GetName() << "> assigned to mismatching geometry");
00675         errName = status;
00676       } else {
00677         MESSAGE( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ")
00678                  << "<" << algo->GetName() << "> misses some hypothesis");
00679       }
00680       if (IsGlobalHypothesis)
00681         globalChecked[ algo->GetDim() ] = true;
00682       theErrors.push_back( SMESH_Gen::TAlgoStateError() );
00683       theErrors.back().Set( errName, algo, IsGlobalHypothesis );
00684     }
00685     ret = false;
00686     break;
00687   }
00688   case SMESH_subMesh::HYP_OK:
00689     algo = aGen->GetAlgo( aMesh, aSubMesh->GetSubShape() );
00690     ret = true;
00691     break;
00692   default: ASSERT(0);
00693   }
00694 
00695   // do not check under algo that hides sub-algos or
00696   // re-start checking NO_ALGO state
00697   ASSERT (algo);
00698   bool isTopLocalAlgo =
00699     ( aTopAlgoDim <= algo->GetDim() && !aGen->IsGlobalHypothesis( algo, aMesh ));
00700   if (!algo->NeedDescretBoundary() || isTopLocalAlgo)
00701   {
00702     bool checkNoAlgo2 = ( algo->NeedDescretBoundary() );
00703     SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false,
00704                                                                      /*complexShapeFirst=*/false);
00705     while ( itsub->more() )
00706     {
00707       // sub-meshes should not be checked further more
00708       SMESH_subMesh* sm = itsub->next();
00709       aCheckedMap.insert( sm );
00710 
00711       if (isTopLocalAlgo)
00712       {
00713         //check algo on sub-meshes
00714         int aTopAlgoDim2 = algo->GetDim();
00715         if (!checkMissing (aGen, aMesh, sm, aTopAlgoDim2,
00716                            globalChecked, checkNoAlgo2, aCheckedMap, theErrors))
00717         {
00718           ret = false;
00719           if (sm->GetAlgoState() == SMESH_subMesh::NO_ALGO )
00720             checkNoAlgo2 = false;
00721         }
00722       }
00723     }
00724   }
00725   return ret;
00726 }
00727 
00728 //=======================================================================
00729 //function : CheckAlgoState
00730 //purpose  : notify on bad state of attached algos, return false
00731 //           if Compute() would fail because of some algo bad state
00732 //=======================================================================
00733 
00734 bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
00735 {
00736   list< TAlgoStateError > errors;
00737   return GetAlgoState( aMesh, aShape, errors );
00738 }
00739 
00740 //=======================================================================
00741 //function : GetAlgoState
00742 //purpose  : notify on bad state of attached algos, return false
00743 //           if Compute() would fail because of some algo bad state
00744 //           theErrors list contains problems description
00745 //=======================================================================
00746 
00747 bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
00748                              const TopoDS_Shape&       theShape,
00749                              list< TAlgoStateError > & theErrors)
00750 {
00751   //MESSAGE("SMESH_Gen::CheckAlgoState");
00752 
00753   bool ret = true;
00754   bool hasAlgo = false;
00755 
00756   SMESH_subMesh* sm = theMesh.GetSubMesh(theShape);
00757   const SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
00758   TopoDS_Shape mainShape = meshDS->ShapeToMesh();
00759 
00760   // -----------------
00761   // get global algos
00762   // -----------------
00763 
00764   const SMESH_Algo* aGlobAlgoArr[] = {0,0,0,0};
00765 
00766   const list<const SMESHDS_Hypothesis*>& listHyp = meshDS->GetHypothesis( mainShape );
00767   list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
00768   for ( ; it != listHyp.end(); it++)
00769   {
00770     const SMESHDS_Hypothesis * aHyp = *it;
00771     if (aHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
00772       continue;
00773 
00774     const SMESH_Algo* algo = dynamic_cast<const SMESH_Algo*> (aHyp);
00775     ASSERT ( algo );
00776 
00777     int dim = algo->GetDim();
00778     aGlobAlgoArr[ dim ] = algo;
00779 
00780     hasAlgo = true;
00781   }
00782 
00783   // --------------------------------------------------------
00784   // info on algos that will be ignored because of ones that
00785   // don't NeedDescretBoundary() attached to super-shapes,
00786   // check that a conform mesh will be produced
00787   // --------------------------------------------------------
00788 
00789 
00790   // find a global algo possibly hiding sub-algos
00791   int dim;
00792   const SMESH_Algo* aGlobIgnoAlgo = 0;
00793   for (dim = 3; dim > 0; dim--)
00794   {
00795     if (aGlobAlgoArr[ dim ] &&
00796         !aGlobAlgoArr[ dim ]->NeedDescretBoundary())
00797     {
00798       aGlobIgnoAlgo = aGlobAlgoArr[ dim ];
00799       break;
00800     }
00801   }
00802 
00803   set<SMESH_subMesh*> aCheckedSubs;
00804   bool checkConform = ( !theMesh.IsNotConformAllowed() );
00805 
00806   // loop on theShape and its sub-shapes
00807   SMESH_subMeshIteratorPtr revItSub = sm->getDependsOnIterator( /*includeSelf=*/true,
00808                                                                 /*complexShapeFirst=*/true);
00809   while ( revItSub->more() )
00810   {
00811     SMESH_subMesh* smToCheck = revItSub->next();
00812     if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX)
00813       break;
00814 
00815     if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked
00816       if (!checkConformIgnoredAlgos (theMesh, smToCheck, aGlobIgnoAlgo,
00817                                      0, checkConform, aCheckedSubs, theErrors))
00818         ret = false;
00819 
00820     if ( smToCheck->GetAlgoState() != SMESH_subMesh::NO_ALGO )
00821       hasAlgo = true;
00822   }
00823 
00824   // ----------------------------------------------------------------
00825   // info on missing hypothesis and find out if all needed algos are
00826   // well defined
00827   // ----------------------------------------------------------------
00828 
00829   //MESSAGE( "---info on missing hypothesis and find out if all needed algos are");
00830 
00831   // find max dim of global algo
00832   int aTopAlgoDim = 0;
00833   for (dim = 3; dim > 0; dim--)
00834   {
00835     if (aGlobAlgoArr[ dim ])
00836     {
00837       aTopAlgoDim = dim;
00838       break;
00839     }
00840   }
00841   bool checkNoAlgo = theMesh.HasShapeToMesh() ? bool( aTopAlgoDim ) : false;
00842   bool globalChecked[] = { false, false, false, false };
00843 
00844   // loop on theShape and its sub-shapes
00845   aCheckedSubs.clear();
00846   revItSub = sm->getDependsOnIterator( /*includeSelf=*/true, /*complexShapeFirst=*/true);
00847   while ( revItSub->more() )
00848   {
00849     SMESH_subMesh* smToCheck = revItSub->next();
00850     if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX)
00851       break;
00852 
00853     if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked
00854       if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim,
00855                          globalChecked, checkNoAlgo, aCheckedSubs, theErrors))
00856       {
00857         ret = false;
00858         if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO )
00859           checkNoAlgo = false;
00860       }
00861   }
00862 
00863   if ( !hasAlgo ) {
00864     ret = false;
00865     INFOS( "None algorithm attached" );
00866     theErrors.push_back( TAlgoStateError() );
00867     theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
00868   }
00869 
00870   return ret;
00871 }
00872 
00873 //=======================================================================
00874 //function : IsGlobalHypothesis
00875 //purpose  : check if theAlgo is attached to the main shape
00876 //=======================================================================
00877 
00878 bool SMESH_Gen::IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& aMesh)
00879 {
00880   SMESH_HypoFilter filter( SMESH_HypoFilter::Is( theHyp ));
00881   return aMesh.GetHypothesis( aMesh.GetMeshDS()->ShapeToMesh(), filter, false );
00882 }
00883 
00884 //=============================================================================
00888 //=============================================================================
00889 
00890 SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh &         aMesh,
00891                                const TopoDS_Shape & aShape,
00892                                TopoDS_Shape*        assignedTo)
00893 {
00894   SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
00895   filter.And( filter.IsApplicableTo( aShape ));
00896 
00897   return (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, assignedTo );
00898 }
00899 
00900 //=============================================================================
00904 //=============================================================================
00905 
00906 StudyContextStruct *SMESH_Gen::GetStudyContext(int studyId)
00907 {
00908   // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
00909 
00910   if (_mapStudyContext.find(studyId) == _mapStudyContext.end())
00911   {
00912     _mapStudyContext[studyId] = new StudyContextStruct;
00913     _mapStudyContext[studyId]->myDocument = new SMESHDS_Document(studyId);
00914   }
00915   StudyContextStruct *myStudyContext = _mapStudyContext[studyId];
00916   return myStudyContext;
00917 }
00918 
00919 //================================================================================
00923 //================================================================================
00924 
00925 int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType)
00926 {
00927   static vector<int> dim;
00928   if ( dim.empty() )
00929   {
00930     dim.resize( TopAbs_SHAPE, -1 );
00931     dim[ TopAbs_COMPOUND ]  = MeshDim_3D;
00932     dim[ TopAbs_COMPSOLID ] = MeshDim_3D;
00933     dim[ TopAbs_SOLID ]     = MeshDim_3D;
00934     dim[ TopAbs_SHELL ]     = MeshDim_3D;
00935     dim[ TopAbs_FACE  ]     = MeshDim_2D;
00936     dim[ TopAbs_WIRE ]      = MeshDim_1D;
00937     dim[ TopAbs_EDGE ]      = MeshDim_1D;
00938     dim[ TopAbs_VERTEX ]    = MeshDim_0D;
00939   }
00940   return dim[ aShapeType ];
00941 }
00942 
00943 //=============================================================================
00947 //=============================================================================
00948 
00949 int SMESH_Gen::GetANewId()
00950 {
00951   return _hypId++;
00952 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS