]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
Implememtation of evaluation for improvement 0019296.
authorskl <skl@opencascade.com>
Mon, 29 Jun 2009 13:26:16 +0000 (13:26 +0000)
committerskl <skl@opencascade.com>
Mon, 29 Jun 2009 13:26:16 +0000 (13:26 +0000)
39 files changed:
idl/SMESH_Gen.idl
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_Gen.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.h
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i.hxx
src/SMESH_SWIG/smeshDC.py
src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx
src/StdMeshers/StdMeshers_CompositeHexa_3D.hxx
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_MEFISTO_2D.hxx
src/StdMeshers/StdMeshers_Penta_3D.cxx
src/StdMeshers/StdMeshers_Penta_3D.hxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Prism_3D.hxx
src/StdMeshers/StdMeshers_Projection_1D.cxx
src/StdMeshers/StdMeshers_Projection_1D.hxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_2D.hxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_Projection_3D.hxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.hxx
src/StdMeshers/StdMeshers_RadialPrism_3D.cxx
src/StdMeshers/StdMeshers_RadialPrism_3D.hxx
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx
src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx
src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx
src/StdMeshers/StdMeshers_UseExisting_1D2D.cxx
src/StdMeshers/StdMeshers_UseExisting_1D2D.hxx

index 7cc93177b00784f00da161877c512d8c8a46051a..9173c3f86dd382bb15a999987e0e8ae954e01126 100644 (file)
@@ -238,6 +238,14 @@ module SMESH
                              in GEOM::GEOM_Object theSubObject )
       raises ( SALOME::SALOME_Exception );
 
+    /*!
+     * Evaluates size of prospective mesh on a shape
+     */
+    long_array  Evaluate(in SMESH_Mesh        theMesh, 
+                        in GEOM::GEOM_Object theSubObject)
+      //inout long_array     theNbElems)
+      raises ( SALOME::SALOME_Exception );
+
     /*!
      * Calculate Mesh as preview till indicated dimension
      * First, verify list of hypothesis associated with the subShape.
index 1ed9cde2574017a112ca4cc5267c057d6d05d1da..0cdaf639b7e0d2941222ff45fc715c76094aaa44 100644 (file)
@@ -54,6 +54,13 @@ class SMDS_MeshNode;
 class SMESH_subMesh;
 class SMESH_MesherHelper;
 
+typedef std::map< SMESH_subMesh*, std::vector<int> > MapShapeNbElems;
+// vector must have size 17:
+// 0 - node, 1 - edge lin, 2 - edge quad, 3 - triangle lin, 4 - triangle quad
+// 5 - quadrangle lin, 6 - quadrangle quad, 7 - polygon, 8 - tetra lin,
+// 9 - tetra quad, 10 - pyramid lin, 11 - pyramid quad, 12 - penta lin,
+// 13 - penta quad, 14 - hexa lin, 15 - hexa quad, 16 -polyhedra
+typedef std::map< SMESH_subMesh*, std::vector<int> >::iterator MapShapeNbElemsItr;
 
 class SMESH_EXPORT SMESH_Algo:public SMESH_Hypothesis
 {
@@ -122,6 +129,16 @@ public:
    */
   virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
 
+  /*!
+   * \brief evaluates size of prospective mesh on a shape
+    * \param aMesh - the mesh
+    * \param aShape - the shape
+    * \param aNbElems - prospective number of elements by types
+    * \retval bool - is a success
+   */
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap) = 0;
+
   /*!
    * \brief Returns a list of compatible hypotheses used to mesh a shape
     * \param aMesh - the mesh 
index 955e1335d1cad3cfc332aeb822780284fa8b6dff..77d3c92ac776478dacfaf1f9e50262b380b4f02e 100644 (file)
@@ -287,6 +287,139 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
   return ret;
 }
 
+
+//=============================================================================
+/*!
+ * Evaluate a mesh
+ */
+//=============================================================================
+
+bool SMESH_Gen::Evaluate(SMESH_Mesh &          aMesh,
+                         const TopoDS_Shape &  aShape,
+                         MapShapeNbElems&      aResMap,
+                        const bool            anUpward,
+                        TSetOfInt*            aShapesId)
+{
+  MESSAGE("SMESH_Gen::Evaluate");
+
+  bool ret = true;
+
+  SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
+
+  const bool includeSelf = true;
+  const bool complexShapeFirst = true;
+  SMESH_subMeshIteratorPtr smIt;
+
+  if ( anUpward ) { // is called from below code here
+    // -----------------------------------------------
+    // mesh all the subshapes starting from vertices
+    // -----------------------------------------------
+    smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
+    while ( smIt->more() ) {
+      SMESH_subMesh* smToCompute = smIt->next();
+
+      // do not mesh vertices of a pseudo shape
+      const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+      //if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
+      //  continue;
+      if ( !aMesh.HasShapeToMesh() ) {
+       if( aShType == TopAbs_VERTEX || aShType == TopAbs_WIRE ||
+           aShType == TopAbs_SHELL )
+         continue;
+      }
+
+      smToCompute->Evaluate(aResMap);
+      if( aShapesId )
+       aShapesId->insert( smToCompute->GetId() );
+    }
+    return ret;
+  }
+  else {
+    // -----------------------------------------------------------------
+    // apply algos that DO NOT require descretized boundaries and DO NOT
+    // support submeshes, starting from the most complex shapes
+    // and collect submeshes with algos that DO support submeshes
+    // -----------------------------------------------------------------
+    list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
+    smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
+    while ( smIt->more() ) {
+      SMESH_subMesh* smToCompute = smIt->next();
+      const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+      const int aShapeDim = GetShapeDim( aSubShape );
+      if ( aShapeDim < 1 ) break;
+      
+      SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
+      if ( algo && !algo->NeedDescretBoundary() ) {
+        if ( algo->SupportSubmeshes() ) {
+          smWithAlgoSupportingSubmeshes.push_back( smToCompute );
+       }
+        else {
+          smToCompute->Evaluate(aResMap);
+         if ( aShapesId )
+           aShapesId->insert( smToCompute->GetId() );
+       }
+      }
+    }
+    // ------------------------------------------------------------
+    // compute submeshes under shapes with algos that DO NOT require
+    // descretized boundaries and DO support submeshes
+    // ------------------------------------------------------------
+    list< SMESH_subMesh* >::reverse_iterator subIt, subEnd;
+    subIt  = smWithAlgoSupportingSubmeshes.rbegin();
+    subEnd = smWithAlgoSupportingSubmeshes.rend();
+    // start from lower shapes
+    for ( ; subIt != subEnd; ++subIt ) {
+      sm = *subIt;
+
+      // get a shape the algo is assigned to
+      TopoDS_Shape algoShape;
+      if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
+        continue; // strange...
+
+      // look for more local algos
+      smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
+      while ( smIt->more() ) {
+        SMESH_subMesh* smToCompute = smIt->next();
+
+        const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+       const int aShapeDim = GetShapeDim( aSubShape );
+       if ( aShapeDim < 1 ) continue;
+
+       const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+
+        SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
+        filter
+          .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
+          .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
+
+        if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+          SMESH_Hypothesis::Hypothesis_Status status;
+          if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
+            // mesh a lower smToCompute starting from vertices
+            Evaluate( aMesh, aSubShape, aResMap, /*anUpward=*/true, aShapesId );
+        }
+      }
+    }
+    // ----------------------------------------------------------
+    // apply the algos that do not require descretized boundaries
+    // ----------------------------------------------------------
+    for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt ) {
+      sm->Evaluate(aResMap);
+      if ( aShapesId )
+       aShapesId->insert( sm->GetId() );
+    }
+
+    // -----------------------------------------------
+    // mesh the rest subshapes starting from vertices
+    // -----------------------------------------------
+    ret = Evaluate( aMesh, aShape, aResMap, /*anUpward=*/true, aShapesId );
+  }
+
+  MESSAGE( "VSR - SMESH_Gen::Evaluate() finished, OK = " << ret);
+  return ret;
+}
+
+
 //=======================================================================
 //function : checkConformIgnoredAlgos
 //purpose  :
index 46c00dc2c9ff6ae9c69e495b12de89e1c17e0f67..57a5af6ebd748363a730cc3534789683b874565f 100644 (file)
@@ -81,6 +81,19 @@ class SMESH_EXPORT  SMESH_Gen
               const ::MeshDimension aDim=::MeshDim_3D,
               TSetOfInt*            aShapesId=0);
 
+  /*!
+   * \brief evaluates size of prospective mesh on a shape 
+   * \param aMesh - the mesh
+   * \param aShape - the shape
+   * \param aResMap - map for prospective numbers of elements
+   * \retval bool - is a success
+   */
+  bool Evaluate(::SMESH_Mesh &        aMesh,
+               const TopoDS_Shape &  aShape,
+               MapShapeNbElems&      aResMap,
+                const bool            anUpward=false,
+                TSetOfInt*            aShapesId=0);
+
   bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   // notify on bad state of attached algos, return false
   // if Compute() would fail because of some algo bad state
index 5a8f63ebf5e781ee360b56096c0ba2cb0db9d7a1..efd05b9c1c94bd64d7eb07f3dc25736a56db8f8a 100644 (file)
@@ -1577,6 +1577,47 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
   return ret;
 }
 
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
+{
+  _computeError.reset();
+
+  bool ret = true;
+
+  if (_subShape.ShapeType() == TopAbs_VERTEX) {
+    std::vector<int> aVec(17);
+    aVec[0] = 1;
+    for(int i=1; i<17; i++) aVec[i] = 0;
+    aResMap.insert(std::make_pair(this,aVec));
+    return ret;
+  }
+
+  SMESH_Gen *gen = _father->GetGen();
+  SMESH_Algo *algo = 0;
+  SMESH_Hypothesis::Hypothesis_Status hyp_status;
+
+  algo = gen->GetAlgo((*_father), _subShape);
+  if(algo) {
+    ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
+    if (!ret) return false;
+
+    TopoDS_Shape shape = _subShape;
+
+    _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
+
+    ret = algo->Evaluate((*_father), shape, aResMap);
+  }
+
+  return ret;
+}
+
+
 //=======================================================================
 /*!
  * \brief Update compute_state by _computeError and send proper events to
index 83de353db90568255afab26cbc2d3ca21f55c265..d4c0468f942dd8600297f5a9332a71dc435dd94a 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Hypothesis.hxx"
 #include "SMESH_ComputeError.hxx"
+#include "SMESH_Algo.hxx"
 
 #include "Utils_SALOME_Exception.hxx"
 
@@ -192,6 +193,8 @@ public:
 
   bool ComputeStateEngine(int event);
 
+  bool Evaluate(MapShapeNbElems& aResMap);
+
   bool IsConform(const SMESH_Algo* theAlgo);
   // check if a conform mesh will be produced by the Algo
 
index dcbe51e7f59c77e0ec7df8aa8aaaa33420285c89..e485f10ffd6ca38272c3335515c31cd101685cef 100644 (file)
@@ -1614,6 +1614,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   case 701:                                    // COMPUTE MESH
   case 711:                                    // PRECOMPUTE MESH
+  case 712:                                    // EVALUATE MESH
     {
       if (checkLock(aStudy)) break;
       startOperation( theCommandID );
@@ -2692,6 +2693,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
   createSMESHAction(  710, "BUILD_COMPOUND",  "ICON_BUILD_COMPOUND" );
   createSMESHAction(  711, "PRECOMPUTE",      "ICON_PRECOMPUTE" );
+  //createSMESHAction(  712, "EVALUATE",        "ICON_EVALUATE" );
+  createSMESHAction(  712, "EVALUATE",        "ICON_COMPUTE" );
   createSMESHAction(  806, "CREATE_GEO_GROUP","ICON_CREATE_GEO_GROUP" );
   createSMESHAction(  801, "CREATE_GROUP",    "ICON_CREATE_GROUP" );
   createSMESHAction(  802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
@@ -2836,6 +2839,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( separator(), meshId, -1 );
   createMenu( 701, meshId, -1 );
   createMenu( 711, meshId, -1 );
+  createMenu( 712, meshId, -1 );
   createMenu( separator(), meshId, -1 );
   createMenu( 801, meshId, -1 );
   createMenu( 806, meshId, -1 );
@@ -2937,6 +2941,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( separator(), meshTb );
   createTool( 701, meshTb );
   createTool( 711, meshTb );
+  createTool( 712, meshTb );
   createTool( separator(), meshTb );
   createTool( 801, meshTb );
   createTool( 806, meshTb );
@@ -3052,6 +3057,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 701, OB, mesh, "&& isComputable" );     // COMPUTE
   createPopupItem( 711, OB, mesh, "&& isComputable" );     // PRECOMPUTE
+  createPopupItem( 712, OB, mesh );                        // EVALUATE
   createPopupItem( 214, OB, mesh_group );                  // UPDATE
   createPopupItem( 900, OB, mesh_group );                  // ADV_INFO
   createPopupItem( 902, OB, mesh );                        // STD_INFO
@@ -3854,6 +3860,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
     case 711: // Precompute mesh
       op = new SMESHGUI_PrecomputeOp();
     break;
+    case 712: // Evaluate mesh
+      op = new SMESHGUI_EvaluateOp();
+    break;
     case 806: // Create group on geom
       op = new SMESHGUI_GroupOnShapeOp();
       break;
index 8e9400a4c785515b442737ec49812fcd29da28c7..55e9ad332e2adcb5077336cbda252944447f4430 100644 (file)
@@ -789,14 +789,14 @@ void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh)
  */
 //=======================================================================
 
-SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent )
+SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval )
  : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
 {
   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
   aDlgLay->setMargin( 0 );
   aDlgLay->setSpacing( SPACING );
 
-  QFrame* aMainFrame = createMainFrame  (mainFrame());
+  QFrame* aMainFrame = createMainFrame(mainFrame(),ForEval);
 
   aDlgLay->addWidget(aMainFrame);
 
@@ -818,7 +818,7 @@ SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg()
 // purpose  : Create frame containing dialog's fields
 //=======================================================================
 
-QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
+QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval)
 {
   QFrame* aFrame = new QFrame(theParent);
 
@@ -827,7 +827,13 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
 
   // constructor
 
-  QGroupBox* aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
+  QGroupBox* aPixGrp;
+  if(ForEval) {
+    aPixGrp = new QGroupBox(tr("EVAL_DLG"), aFrame);
+  }
+  else {
+    aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
+  }
   QButtonGroup* aBtnGrp = new QButtonGroup(this);
   QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
   aPixGrpLayout->setMargin(MARGIN); aPixGrpLayout->setSpacing(SPACING);
@@ -931,8 +937,7 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
 //================================================================================
 
 SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
-  : SMESHGUI_Operation(),
-    myCompDlg( 0 )
+  : SMESHGUI_Operation(), myCompDlg( 0 )
 {
   myTShapeDisplayer = new SMESH::TShapeDisplayer();
   myBadMeshDisplayer = 0;
@@ -1420,7 +1425,7 @@ SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
   if ( !myCompDlg )
   {
     SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
-    me->myCompDlg = new SMESHGUI_ComputeDlg( desktop() );
+    me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), false );
     // connect signals and slots
     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
@@ -1908,3 +1913,352 @@ int SMESHGUI_PrecomputeDlg::getPreviewMode() const
 {
   return myPreviewMode->currentId();
 }
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
+ : SMESHGUI_BaseComputeOp()
+{
+}
+
+
+//================================================================================
+/*!
+ * \brief Desctructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::~SMESHGUI_EvaluateOp()
+{
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+void SMESHGUI_EvaluateOp::startOperation()
+{
+  SMESHGUI_BaseComputeOp::evaluateDlg();
+  SMESHGUI_BaseComputeOp::startOperation();
+  evaluateMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_EvaluateOp::dlg() const
+{
+  return evaluateDlg();
+}
+
+//================================================================================
+/*!
+ * \brief evaluaateMesh()
+*/
+//================================================================================
+
+void SMESHGUI_BaseComputeOp::evaluateMesh()
+{
+  // EVALUATE MESH
+
+  SMESH::MemoryReserve aMemoryReserve;
+
+  SMESH::compute_error_array_var aCompErrors;
+  QString                        aHypErrors;
+
+  bool evaluateFailed = true, memoryLack = false;
+  std::vector<int> aResVec(18);
+
+  _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
+  bool hasShape = myMesh->HasShapeToMesh();
+  bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
+  if ( shapeOK && aMeshSObj )
+  {
+    myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+    SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
+    SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
+    if ( errors->length() > 0 ) {
+      aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
+    }
+    SUIT_OverrideCursor aWaitCursor;
+    try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+      OCC_CATCH_SIGNALS;
+#endif
+      SMESH::long_array_var aVec = gen->Evaluate(myMesh, myMainShape);
+      for(int i=0; i<17; i++) {
+       aResVec[i] = aVec[i];
+      }
+    }
+    catch(const SALOME::SALOME_Exception & S_ex){
+      memoryLack = true;
+    }
+
+    try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+      OCC_CATCH_SIGNALS;
+#endif
+      aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
+    }
+    catch(const SALOME::SALOME_Exception & S_ex){
+      memoryLack = true;
+    }
+  }
+
+  if ( memoryLack )
+    aMemoryReserve.release();
+
+  myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
+
+  // SHOW ERRORS
+  
+  bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
+  bool noHypoError = ( aHypErrors.isEmpty() );
+
+  //SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+  //int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
+
+  bool isShowResultDlg = true;
+  //if( noHypoError )
+  //switch( aNotifyMode ) {
+  //case 0: // show the mesh computation result dialog NEVER
+  //isShowResultDlg = false;
+  //commit();
+  //break;
+  //case 1: // show the mesh computation result dialog if there are some errors
+  //if ( memoryLack || !noHypoError )
+  //  isShowResultDlg = true;
+  //else
+  //{
+  //  isShowResultDlg = false;
+  //  commit();
+  //}
+  //break;
+  //default: // show the result dialog after each mesh computation
+  //isShowResultDlg = true;
+  //}
+
+  // SHOW RESULTS
+  if ( isShowResultDlg )
+    //showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors );
+    showEvaluateResult( aResVec, memoryLack, noCompError, aCompErrors,
+                       noHypoError, aHypErrors);
+}
+
+
+void SMESHGUI_BaseComputeOp::showEvaluateResult(std::vector<int> theVec,
+                                               const bool theMemoryLack,
+                                               const bool theNoCompError,
+                                               SMESH::compute_error_array_var& theCompErrors,
+                                               const bool theNoHypoError,
+                                               const QString& theHypErrors)
+{
+  bool hasShape = myMesh->HasShapeToMesh();
+  SMESHGUI_ComputeDlg* aCompDlg = evaluateDlg();
+  aCompDlg->myMemoryLackGroup->hide();
+
+  if ( theMemoryLack )
+  {
+    aCompDlg->myMemoryLackGroup->show();
+    aCompDlg->myFullInfo->hide();
+    aCompDlg->myBriefInfo->hide();
+    aCompDlg->myHypErrorGroup->hide();
+    aCompDlg->myCompErrorGroup->hide();
+  }
+  else if ( theNoCompError && theNoHypoError )
+  {
+    //aCompDlg->myFullInfo->SetInfoByMesh( myMesh );
+    aCompDlg->myFullInfo->SetInfoByEval( theVec );
+    aCompDlg->myFullInfo->show();
+    aCompDlg->myBriefInfo->hide();
+    aCompDlg->myHypErrorGroup->hide();
+    aCompDlg->myCompErrorGroup->hide();
+  }
+  else
+  {
+    QTableWidget* tbl = aCompDlg->myTable;
+    //aCompDlg->myBriefInfo->SetInfoByMesh( myMesh );
+    aCompDlg->myBriefInfo->SetInfoByEval( theVec );
+    aCompDlg->myBriefInfo->show();
+    aCompDlg->myFullInfo->hide();
+
+    if ( theNoHypoError ) {
+      aCompDlg->myHypErrorGroup->hide();
+    }
+    else {
+      aCompDlg->myHypErrorGroup->show();
+      aCompDlg->myHypErrorLabel->setText( theHypErrors );
+    }
+
+    if ( theNoCompError ) {
+      aCompDlg->myCompErrorGroup->hide();
+    }
+    else {
+      aCompDlg->myCompErrorGroup->show();
+
+      aCompDlg->myPublishBtn->hide();
+      aCompDlg->myShowBtn->hide();
+
+      // fill table of errors
+      tbl->setRowCount( theCompErrors->length() );
+      if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
+      else             tbl->showColumn( COL_SHAPE );
+      tbl->setColumnWidth( COL_ERROR, 200 );
+
+      bool hasBadMesh = false;
+      for ( int row = 0; row < theCompErrors->length(); ++row )
+      {
+        SMESH::ComputeError & err = theCompErrors[ row ];
+
+       QString text = err.algoName.in();
+       if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
+       else tbl->item( row, COL_ALGO )->setText( text );
+
+       text = SMESH::errorText( err.code, err.comment.in() );
+       if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
+       else tbl->item( row, COL_ERROR )->setText( text );
+
+       text = QString("%1").arg( err.subShapeID );
+       if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
+       else tbl->item( row, COL_SHAPEID )->setText( text );
+
+        text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
+       if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
+       else tbl->item( row, COL_SHAPE )->setText( text );
+
+        text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
+       if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
+       else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
+
+        text = err.hasBadMesh ? "hasBadMesh" : "";
+       if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
+       else tbl->item( row, COL_BAD_MESH )->setText( text );
+        if ( err.hasBadMesh ) hasBadMesh = true;
+
+        //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
+        tbl->resizeRowToContents( row );
+      }
+      tbl->resizeColumnToContents( COL_ALGO );
+      tbl->resizeColumnToContents( COL_SHAPE );
+
+      if ( hasBadMesh )
+        aCompDlg->myBadMeshBtn->show();
+      else
+        aCompDlg->myBadMeshBtn->hide();
+
+      tbl->setCurrentCell(0,0);
+      currentCellChanged(); // to update buttons
+    }
+  }
+  // show dialog and wait, becase Compute can be invoked from Preview operation
+  //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
+  aCompDlg->show();
+}
+
+
+// =========================================================================================
+/*!
+ * \brief Set mesh info
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshInfosBox::SetInfoByEval(std::vector<int> theVec)
+{
+  // nodes
+  myNbNode     ->setText( QString("%1").arg( theVec[0] ));
+
+  // edges
+  int nbTot = theVec[1] + theVec[2];
+  myNbEdge     ->setText( QString("%1").arg( nbTot ));
+  myNbLinEdge  ->setText( QString("%1").arg( theVec[1] ));
+  myNbQuadEdge ->setText( QString("%1").arg( theVec[2] ));
+
+  // faces
+  nbTot = 0;
+  int i = 3;
+  for(; i<=7; i++) nbTot += theVec[i];
+  myNbFace     ->setText( QString("%1").arg( nbTot ));
+  myNbLinFace  ->setText( QString("%1").arg( theVec[3] + theVec[5] ));
+  myNbQuadFace ->setText( QString("%1").arg( theVec[4] + theVec[6] ));
+
+  // volumes
+  nbTot = 0;
+  for(i=8; i<=16; i++) nbTot += theVec[i];
+  int nbLin = 0, nbQua = 0;; 
+  for(i=0; i<=3; i++) {
+    nbLin += theVec[8+2*i];
+    nbQua += theVec[9+2*i];
+  }
+  myNbVolum    ->setText( QString("%1").arg( nbTot ));
+  myNbLinVolum ->setText( QString("%1").arg( nbLin ));
+  myNbQuadVolum->setText( QString("%1").arg( nbQua ));
+
+  if ( myFull )
+  {
+    // triangles
+    myNbTrai     ->setText( QString("%1").arg( theVec[3] + theVec[4] ));
+    myNbLinTrai  ->setText( QString("%1").arg( theVec[3] ));
+    myNbQuadTrai ->setText( QString("%1").arg( theVec[4] ));
+    // quadrangles
+    myNbQuad     ->setText( QString("%1").arg( theVec[5] + theVec[6] ));
+    myNbLinQuad  ->setText( QString("%1").arg( theVec[5] ));
+    myNbQuadQuad ->setText( QString("%1").arg( theVec[6] ));
+    // poligones
+    myNbPolyg    ->setText( QString("%1").arg( theVec[7] ));
+
+    // tetras
+    myNbTetra    ->setText( QString("%1").arg( theVec[8] + theVec[9] ));
+    myNbLinTetra ->setText( QString("%1").arg( theVec[8] ));
+    myNbQuadTetra->setText( QString("%1").arg( theVec[9] ));
+    // hexas
+    myNbHexa     ->setText( QString("%1").arg( theVec[14] + theVec[15] ));
+    myNbLinHexa  ->setText( QString("%1").arg( theVec[14] ));
+    myNbQuadHexa ->setText( QString("%1").arg( theVec[15] ));
+    // pyras
+    myNbPyra     ->setText( QString("%1").arg( theVec[10] + theVec[11] ));
+    myNbLinPyra  ->setText( QString("%1").arg( theVec[10] ));
+    myNbQuadPyra ->setText( QString("%1").arg( theVec[11] ));
+    // prisms
+    myNbPrism    ->setText( QString("%1").arg( theVec[12] + theVec[13] ));
+    myNbLinPrism ->setText( QString("%1").arg( theVec[12] ));
+    myNbQuadPrism->setText( QString("%1").arg( theVec[13] ));
+    // polyedres
+    myNbPolyh    ->setText( QString("%1").arg( theVec[16] ));
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of evaluate operation
+ * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation
+ */
+//================================================================================
+
+SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::evaluateDlg() const
+{
+  if ( !myCompDlg )
+  {
+    SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
+    me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), true );
+    // connect signals and slots
+    connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
+    connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
+    connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
+    QTableWidget* aTable = me->table();
+    connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
+    connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
+  }
+  return myCompDlg;
+}
+
index 9a84f8a1c26b919fbf8160449528def81f33af30..c07e8674668ddc4dbfd5f9143283f7338a8cce31 100644 (file)
@@ -51,6 +51,7 @@ class QLabel;
 class QtxComboBox;
 class SMESHGUI_ComputeDlg;
 class SMESHGUI_PrecomputeDlg;
+//class SMESHGUI_EvaluateDlg;
 class SMESHGUI_MeshEditPreview;
 
 class SMESH::compute_error_array;
@@ -82,6 +83,15 @@ protected:
                                                    SMESH::compute_error_array_var&,
                                                    const bool,
                                                    const QString& );
+  //SMESHGUI_EvaluateDlg*          evaluateDlg() const;
+  SMESHGUI_ComputeDlg*           evaluateDlg() const;
+  void                           evaluateMesh();
+  void                           showEvaluateResult(std::vector<int> theVec,
+                                                   const bool,
+                                                   const bool,
+                                                   SMESH::compute_error_array_var&,
+                                                   const bool,
+                                                   const QString&);
     
 protected slots:
   virtual bool                   onApply();
@@ -95,6 +105,7 @@ private:
 
 private:
   QPointer<SMESHGUI_ComputeDlg>  myCompDlg;
+  //QPointer<SMESHGUI_EvaluateDlg> myEvalDlg;
 
 protected:
   SMESH::SMESH_Mesh_var            myMesh;
@@ -157,6 +168,25 @@ private:
   SMESHGUI_MeshEditPreview*      myPreviewDisplayer;
 };
 
+/*!
+ * \brief Operation to evaluate a mesh and show result
+ */
+class SMESHGUI_EXPORT SMESHGUI_EvaluateOp: public SMESHGUI_BaseComputeOp
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_EvaluateOp();
+  virtual ~SMESHGUI_EvaluateOp();
+
+  virtual LightApp_Dialog*       dlg() const;
+
+protected:
+  virtual void                   startOperation();
+
+protected slots:
+};
+
 /*!
  * \brief Box showing mesh info
  */
@@ -170,6 +200,8 @@ public:
 
   void    SetInfoByMesh( SMESH::SMESH_Mesh_var );
 
+  void    SetInfoByEval( std::vector<int> theVec );
+
 private:
   bool    myFull;
   QLabel* myNbNode;
@@ -213,11 +245,11 @@ class SMESHGUI_EXPORT SMESHGUI_ComputeDlg : public SMESHGUI_Dialog
   Q_OBJECT
 
 public:
-  SMESHGUI_ComputeDlg( QWidget* );
+  SMESHGUI_ComputeDlg( QWidget*, bool );
   virtual ~SMESHGUI_ComputeDlg();
 
 protected:
-  QFrame*                      createMainFrame( QWidget* );
+  QFrame*                      createMainFrame( QWidget*, bool );
 
   QLabel*                      myMeshName;
   QGroupBox*                   myMemoryLackGroup;
@@ -260,4 +292,36 @@ private:
 };
 
 
+/*!
+ * \brief Dialog to evaluate a mesh and show result
+ */
+/*
+class SMESHGUI_EXPORT SMESHGUI_EvaluateDlg : public SMESHGUI_Dialog
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_EvaluateDlg( QWidget* );
+  virtual ~SMESHGUI_EvaluateDlg();
+
+protected:
+  QFrame*                      createMainFrame( QWidget* );
+
+  QLabel*                      myMeshName;
+  QGroupBox*                   myMemoryLackGroup;
+  QGroupBox*                   myCompErrorGroup;
+  QGroupBox*                   myHypErrorGroup;
+  QLabel*                      myHypErrorLabel;
+  QTableWidget*                myTable;
+  QPushButton*                 myShowBtn;
+  QPushButton*                 myPublishBtn;
+  QPushButton*                 myBadMeshBtn;
+
+  SMESHGUI_MeshInfosBox*       myBriefInfo;
+  SMESHGUI_MeshInfosBox*       myFullInfo;
+
+  friend class SMESHGUI_BaseComputeOp;
+};
+*/
+
 #endif // SMESHGUI_COMPUTEDLG_H
index 27f0d14532827573a26ed37666990bd0a8d01b4b..10a95c873ddabec75336637bc1650dbf0f079794 100644 (file)
             <source>MEN_PRECOMPUTE</source>
             <translation>Preview</translation>
         </message>
+        <message>
+            <source>MEN_EVALUATE</source>
+            <translation>Evaluate</translation>
+        </message>
         <message>
             <source>MEN_CONNECTION</source>
             <translation>Borders at Multi-Connection</translation>
@@ -1987,6 +1991,10 @@ Consider saving your work before application crash</translation>
             <source>STB_PRECOMPUTE</source>
             <translation>Preview</translation>
         </message>
+        <message>
+            <source>STB_EVALUATE</source>
+            <translation>Evaluate</translation>
+        </message>
         <message>
             <source>STB_CONNECTION</source>
             <translation>Borders at Multi-Connection</translation>
@@ -2469,6 +2477,10 @@ Consider saving your work before application crash</translation>
             <source>TOP_PRECOMPUTE</source>
             <translation>Preview</translation>
         </message>
+        <message>
+            <source>TOP_EVALUATE</source>
+            <translation>Evaluate</translation>
+        </message>
         <message>
             <source>TOP_CONNECTION</source>
             <translation>Borders at Multi-Connection</translation>
@@ -3215,6 +3227,10 @@ Please, create VTK viewer and try again</translation>
             <source>CONSTRUCTOR</source>
             <translation>Compute mesh</translation>
         </message>
+        <message>
+            <source>EVAL_DLG</source>
+            <translation>Evaluate mesh</translation>
+        </message>
         <message>
             <source>ERRORS</source>
             <translation>Errors</translation>
index eb49db1b9b532448aa3528a8e8d02aacebaf6f70..2dcd38c07cffb6fd2abe1b56d3ce9b0aaf8c1068 100644 (file)
@@ -1607,6 +1607,93 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
   return result._retn();
 }
 
+
+//=============================================================================
+/*!
+ *  SMESH_Gen_i::Evaluate
+ *
+ *  Evaluate mesh on a shape
+ */
+//=============================================================================
+
+//CORBA::Boolean 
+SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+                                        GEOM::GEOM_Object_ptr theShapeObject)
+//                                     SMESH::long_array& theNbElems)
+     throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" );
+
+  if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+                                  SALOME::BAD_PARAM );
+
+  if ( CORBA::is_nil( theMesh ) )
+    THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+                                  SALOME::BAD_PARAM );
+
+  SMESH::long_array_var nbels = new SMESH::long_array;
+
+  // Update Python script
+  TPythonDump() << "theNbElems = " << this << ".Evaluate( "
+                << theMesh << ", " << theShapeObject << ")";
+
+  try {
+    // get mesh servant
+    SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+    ASSERT( meshServant );
+    if ( meshServant ) {
+      // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
+      meshServant->CheckGeomGroupModif();
+      // get local TopoDS_Shape
+      TopoDS_Shape myLocShape;
+      if(theMesh->HasShapeToMesh())
+        myLocShape = GeomObjectToShape( theShapeObject );
+      else
+        myLocShape = SMESH_Mesh::PseudoShape();
+      // call implementation compute
+      ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+      MapShapeNbElems aResMap;
+      CORBA::Boolean ret = myGen.Evaluate( myLocMesh, myLocShape, aResMap);
+      MapShapeNbElemsItr anIt = aResMap.begin();
+      vector<int> aResVec(17);
+      int i = 0;
+      for(; i<17; i++) aResVec[i] = 0;
+      for(; anIt!=aResMap.end(); anIt++) {
+       // 0 - node, 1 - edge lin, 2 - edge quad,
+       // 3 - triangle lin, 4 - triangle quad
+       // 5 - quadrangle lin, 6 - quadrangle quad
+       // 7 - polygon, 8 - tetra lin, 9 - tetra quad
+       // 10 - pyramid lin, 11 - pyramid quad,
+       // 12 - penta lin, 13 - penta quad, 14 - hexa lin,
+       // 15 - hexa quad, 16 -polyhedra
+       vector<int> aVec = (*anIt).second;
+       for(i=0; i<17; i++) {
+         aResVec[i] += aVec[i];
+       }
+      }
+      nbels->length(17);
+      for(i=0; i<17; i++) {
+       nbels[i] = aResVec[i];
+      }
+      cout<<endl;
+      return nbels._retn();
+    }
+  }
+  catch ( std::bad_alloc ) {
+    INFOS( "Evaluate(): lack of memory" );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    INFOS( "Evaluate(): catch exception "<< S_ex.what() );
+  }
+  catch ( ... ) {
+    INFOS( "Evaluate(): unknown exception " );
+  }
+
+  return nbels._retn();
+}
+
 //================================================================================
 /*!
  * \brief Return geometrical object the given element is built on
index d10b59ef207a97b097625d25e718712d68e3675c..d84c73fc16e1aa6dbe235f2011bd02cdc7f4c5af 100644 (file)
@@ -246,6 +246,13 @@ public:
                                                GEOM::GEOM_Object_ptr  theShapeObject )
     throw ( SALOME::SALOME_Exception );
 
+  // Evaluate mesh on a shape
+  //CORBA::Boolean 
+  SMESH::long_array* Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+                              GEOM::GEOM_Object_ptr theShapeObject)
+    //                              SMESH::long_array& theNbElems)
+    throw ( SALOME::SALOME_Exception );
+
   // Returns true if mesh contains enough data to be computed
   CORBA::Boolean IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
                                    GEOM::GEOM_Object_ptr theShapeObject )
index 9d8a0f5d76b45faaffa1ca20643b585ca3b8191a..07a467e1c3139da1c3ecb56f3f83b3ca61710cc4 100644 (file)
@@ -1069,6 +1069,17 @@ class Mesh:
             return Mesh_Prism3D(self,  geom)
         return Mesh_RadialPrism3D(self,  geom)
 
+    ## Evaluates size of prospective mesh on a shape
+    #  @return True or False
+    def Evaluate(self, geom=0):
+        if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object):
+            if self.geom == 0:
+                geom = self.mesh.GetShapeToMesh()
+            else:
+                geom = self.geom
+        return self.smeshpyD.Evaluate(self.mesh, geom)
+
+
     ## Computes the mesh and returns the status of the computation
     #  @return True or False
     #  @ingroup l2_construct
index 8254219d2c21fb05ed471bae5ca3b112dd223365..d489b3d769ae11a332f7b04cc19234316360765a 100644 (file)
@@ -43,6 +43,7 @@
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
@@ -507,6 +508,213 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   return true;
 }
 
+
+//=======================================================================
+//function : GetNb2d
+//purpose  : auxilary for Evaluate
+//=======================================================================
+int GetNb2d(_QuadFaceGrid* QFG, SMESH_Mesh& theMesh,
+           MapShapeNbElems& aResMap)
+{
+  int nb2d = 0;
+  _QuadFaceGrid::TChildIterator aCI = QFG->GetChildren();
+  while( aCI.more() ) {
+    const _QuadFaceGrid& currChild = aCI.next();
+    SMESH_subMesh *sm = theMesh.GetSubMesh(currChild.GetFace());
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb2d += Max(aVec[5],aVec[6]);
+    }
+  }
+  return nb2d;
+}
+
+
+//================================================================================
+/*!
+ *  Evaluate
+ */
+//================================================================================
+
+bool StdMeshers_CompositeHexa_3D::Evaluate(SMESH_Mesh& theMesh,
+                                          const TopoDS_Shape& theShape,
+                                          MapShapeNbElems& aResMap)
+{
+  SMESH_MesherHelper aTool(theMesh);
+  bool _quadraticMesh = aTool.IsQuadraticSubMesh(theShape);
+
+
+  // -------------------------
+  // Try to find 6 side faces
+  // -------------------------
+  vector< _QuadFaceGrid > boxFaces; boxFaces.reserve( 6 );
+  TopExp_Explorer exp;
+  int iFace, nbFaces = 0;
+  for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
+  {
+    _QuadFaceGrid f;
+    if ( !f.Init( TopoDS::Face( exp.Current() )))
+      //return error (COMPERR_BAD_SHAPE);
+      return false;
+    bool isContinuous = false;
+    for ( int i=0; i < boxFaces.size() && !isContinuous; ++i )
+      isContinuous = boxFaces[ i ].AddContinuousFace( f );
+    if ( !isContinuous )
+      boxFaces.push_back( f );
+  }
+  // Check what we have
+  if ( boxFaces.size() != 6 && nbFaces != 6)
+    //return error
+    //  (COMPERR_BAD_SHAPE,
+    //   SMESH_Comment("Can't find 6 sides of a box. Number of found sides - ")<<boxFaces.size());
+    return false;
+
+  if ( boxFaces.size() != 6 && nbFaces == 6 ) { // strange ordinary box with continuous faces
+    boxFaces.resize( 6 );
+    iFace = 0;
+    for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++iFace )
+      boxFaces[ iFace ].Init( TopoDS::Face( exp.Current() ) );
+  }
+
+  // ----------------------------------------
+  // Find out position of faces within a box
+  // ----------------------------------------
+
+  _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
+  // start from a bottom face
+  fBottom = &boxFaces[0];
+  // find vertical faces
+  fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces );
+  fLeft  = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces );
+  fBack  = fBottom->FindAdjacentForSide( Q_TOP, boxFaces );
+  fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces );
+  // check the found
+  if ( !fFront || !fBack || !fLeft || !fRight )
+    //return error(COMPERR_BAD_SHAPE);
+    return false;
+  // top face
+  fTop = 0;
+  int i = 1;
+  for(; i < boxFaces.size() && !fTop; ++i ) {
+    fTop = & boxFaces[ i ];
+    if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight )
+      fTop = 0;
+  }
+  // set bottom of the top side
+  if ( !fTop->SetBottomSide( fFront->GetSide( Q_TOP ) )) {
+    if ( !fFront->IsComplex() )
+      //return error( ERR_LI("Error in StdMeshers_CompositeHexa_3D::Compute()"));
+      return false;
+    else {
+      _QuadFaceGrid::TChildIterator chIt = fFront->GetChildren();
+      while ( chIt.more() ) {
+        const _QuadFaceGrid& frontChild = chIt.next();
+        if ( fTop->SetBottomSide( frontChild.GetSide( Q_TOP )))
+          break;
+      }
+    }
+  }
+  if ( !fTop )
+    //return error(COMPERR_BAD_SHAPE);
+    return false;
+
+
+  TopTools_SequenceOfShape BottomFaces;
+  _QuadFaceGrid::TChildIterator aCI = fBottom->GetChildren();
+  while( aCI.more() ) {
+    const _QuadFaceGrid& currChild = aCI.next();
+    BottomFaces.Append(currChild.GetFace());
+  }
+  // find boundary edges and internal nodes for bottom face
+  TopTools_SequenceOfShape BndEdges;
+  int nb0d_in = 0;
+  //TopTools_MapOfShape BndEdges;
+  for(i=1; i<=BottomFaces.Length(); i++) {
+    for (TopExp_Explorer exp(BottomFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+      int nb0 = 0;
+      SMESH_subMesh *sm = theMesh.GetSubMesh(exp.Current());
+      if( sm ) {
+       MapShapeNbElemsItr anIt = aResMap.find(sm);
+       if( anIt == aResMap.end() ) continue;
+       std::vector<int> aVec = (*anIt).second;
+       nb0 = aVec[0];
+      }
+      int j = 1;
+      for(; j<=BndEdges.Length(); j++) {
+       if( BndEdges.Value(j) == exp.Current() ) {
+         // internal edge => remove it
+         BndEdges.Remove(j);
+         nb0d_in += nb0;
+         break;
+       }
+      }
+      if( j > BndEdges.Length() ) {
+       BndEdges.Append(exp.Current());
+      }
+      //if( BndEdges.Contains(exp.Current()) ) {
+      //BndEdges.Remove( exp.Current() );
+      //}
+      //else {
+      //BndEdges.Add( exp.Current() );
+      //}
+    }
+  }
+
+  // find number of 1d elems for bottom face
+  int nb1d = 0;
+  for(i=1; i<=BndEdges.Length(); i++) {
+    SMESH_subMesh *sm = theMesh.GetSubMesh(BndEdges.Value(i));
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb1d += Max(aVec[1],aVec[2]);
+    }
+  }
+
+  // find number of 2d elems on side faces
+  int nb2d = 0;
+  nb2d += GetNb2d(fFront, theMesh, aResMap);
+  nb2d += GetNb2d(fRight, theMesh, aResMap);
+  nb2d += GetNb2d(fBack, theMesh, aResMap);
+  nb2d += GetNb2d(fLeft, theMesh, aResMap);
+
+  // find number of 2d elems and nodes on bottom faces
+  int nb0d=0, nb2d_3=0, nb2d_4=0;
+  for(i=1; i<=BottomFaces.Length(); i++) {
+    SMESH_subMesh *sm = theMesh.GetSubMesh(BottomFaces.Value(i));
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb0d += aVec[0];
+      nb2d_3 += Max(aVec[3],aVec[4]);
+      nb2d_4 += Max(aVec[5],aVec[6]);
+    }
+  }
+  nb0d += nb0d_in;
+
+  std::vector<int> aResVec(17);
+  for(int i=0; i<17; i++) aResVec[i] = 0;
+  if(_quadraticMesh) {
+    aResVec[13] = nb2d_3 * ( nb2d/nb1d );
+    aResVec[15] = nb2d_4 * ( nb2d/nb1d );
+    aResVec[0] = nb0d * ( 2*nb2d/nb1d - 1 );
+  }
+  else {
+    aResVec[0] = nb0d * ( nb2d/nb1d - 1 );
+    aResVec[12] = nb2d_3 * ( nb2d/nb1d );
+    aResVec[14] = nb2d_4 * ( nb2d/nb1d );
+  }
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
+
+
 //================================================================================
 /*!
  * \brief constructor of non-initialized _QuadFaceGrid
index 09b687fc17f9c0815f9c00221d0c95add6f3a766..8fd14ba06747e5a206c1ee14fec1d2005ff53c7b 100644 (file)
@@ -50,6 +50,9 @@ public:
   virtual bool Compute(SMESH_Mesh&         aMesh,
                       const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   virtual bool CheckHypothesis(SMESH_Mesh&         aMesh,
                                const TopoDS_Shape& aShape,
                                Hypothesis_Status&  aStatus);
index 769d996c5f57a24a80c1b599169b8e9c2565764c..f0738bb8921c82a6f283584cd59ddf93ff62dfb2 100644 (file)
@@ -48,6 +48,8 @@
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
 #include <gp_Pnt2d.hxx>
 
@@ -58,7 +60,11 @@ typedef SMESH_Comment TComm;
 
 using namespace std;
 
-static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &);
+static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &,
+                                                   const TopoDS_Shape &);
+
+static bool EvaluatePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &,
+                                   MapShapeNbElems &);
 
 //=============================================================================
 /*!
@@ -736,6 +742,118 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   return ClearAndReturn( aQuads, true );
 }
 
+
+//=============================================================================
+/*!
+ *  Evaluate
+ */
+//=============================================================================
+
+bool StdMeshers_Hexa_3D::Evaluate(SMESH_Mesh & aMesh,
+                                 const TopoDS_Shape & aShape,
+                                 MapShapeNbElems& aResMap)
+{
+  vector < SMESH_subMesh * >meshFaces;
+  TopTools_SequenceOfShape aFaces;
+  for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+    aFaces.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+    ASSERT(aSubMesh);
+    meshFaces.push_back(aSubMesh);
+  }
+  if (meshFaces.size() != 6) {
+    //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block");
+    static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen());
+    return compositeHexa.Evaluate(aMesh, aShape, aResMap);
+  }
+  
+  int i = 0;
+  for(; i<6; i++) {
+    //TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+    TopoDS_Shape aFace = aFaces.Value(i+1);
+    SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+    string algoName = algo->GetName();
+    bool isAllQuad = false;
+    if (algoName == "Quadrangle_2D") {
+      MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      int nbtri = Max(aVec[3],aVec[4]);
+      if( nbtri == 0 )
+       isAllQuad = true;
+    }
+    if ( ! isAllQuad ) {
+      return EvaluatePentahedralMesh(aMesh, aShape, aResMap);
+    }
+  }
+  
+  // find number of 1d elems for 1 face
+  int nb1d = 0;
+  TopTools_MapOfShape Edges1;
+  bool IsQuadratic = false;
+  bool IsFirst = true;
+  for (TopExp_Explorer exp(aFaces.Value(1), TopAbs_EDGE); exp.More(); exp.Next()) {
+    Edges1.Add(exp.Current());
+    SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb1d += Max(aVec[1],aVec[2]);
+      if(IsFirst) {
+       IsQuadratic = (aVec[2] > aVec[1]);
+       IsFirst = false;
+      }
+    }
+  }
+  // find face opposite to 1 face
+  int OppNum = 0;
+  for(i=2; i<=6; i++) {
+    bool IsOpposite = true;
+    for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+      if( Edges1.Contains(exp.Current()) ) {
+       IsOpposite = false;
+       break;
+      }
+    }
+    if(IsOpposite) {
+      OppNum = i;
+      break;
+    }
+  }
+  // find number of 2d elems on side faces
+  int nb2d = 0;
+  for(i=2; i<=6; i++) {
+    if( i == OppNum ) continue;
+    MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    nb2d += Max(aVec[5],aVec[6]);
+  }
+  
+  MapShapeNbElemsItr anIt = aResMap.find( meshFaces[0] );
+  std::vector<int> aVec = (*anIt).second;
+  int nb2d_face0 = Max(aVec[5],aVec[6]);
+  int nb0d_face0 = aVec[0];
+
+  std::vector<int> aResVec(17);
+  for(int i=0; i<17; i++) aResVec[i] = 0;
+  if(IsQuadratic) {
+    aResVec[15] = nb2d_face0 * ( nb2d/nb1d );
+    int nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
+    aResVec[0] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+  }
+  else {
+    aResVec[0] = nb0d_face0 * ( nb2d/nb1d - 1 );
+    aResVec[14] = nb2d_face0 * ( nb2d/nb1d );
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  *  
@@ -1056,3 +1174,33 @@ SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &         aMesh,
 }
 
 
+//=======================================================================
+//function : EvaluatePentahedralMesh
+//purpose  : 
+//=======================================================================
+
+bool EvaluatePentahedralMesh(SMESH_Mesh & aMesh,
+                            const TopoDS_Shape & aShape,
+                            MapShapeNbElems& aResMap)
+{
+  StdMeshers_Penta_3D anAlgo;
+  bool bOK = anAlgo.Evaluate(aMesh, aShape, aResMap);
+
+  //err = anAlgo.GetComputeError();
+  //if ( !bOK && anAlgo.ErrorStatus() == 5 )
+  if( !bOK ) {
+    static StdMeshers_Prism_3D * aPrism3D = 0;
+    if ( !aPrism3D ) {
+      SMESH_Gen* gen = aMesh.GetGen();
+      aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
+    }
+    SMESH_Hypothesis::Hypothesis_Status aStatus;
+    if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
+      return aPrism3D->Evaluate(aMesh, aShape, aResMap);
+    }
+  }
+
+  return bOK;
+}
+
+
index 24927ef5ae273c1f14cbee8b8cf62fd92b1c77cb..d34d812dd81e48335a17ce18b0e7f7f21bc6e8cc 100644 (file)
@@ -77,6 +77,9 @@ public:
                       const TopoDS_Shape& aShape)
     /*throw (SALOME_Exception)*/;
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   static TopoDS_Vertex OppositeVertex(const TopoDS_Vertex& aVertex,
                                       const TopTools_IndexedMapOfShape& aQuads0Vertices,
                                       FaceQuadStruct* aQuads[6]);
index 45339814920fe3c24fee71cd55e7541bb88bd41e..f842eb87b01bc6bd88d813f90ffeebfbc6202084 100644 (file)
@@ -50,6 +50,7 @@
 
 #include <BRepTools.hxx>
 #include <BRep_Tool.hxx>
+#include <Geom_Curve.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom_Surface.hxx>
 #include <TopExp.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <gp_Pnt2d.hxx>
 
+#include <BRep_Tool.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+
 using namespace std;
 
 //=============================================================================
@@ -282,6 +287,79 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   return isOk;
 }
 
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::Evaluate(SMESH_Mesh & aMesh,
+                                    const TopoDS_Shape & aShape,
+                                    MapShapeNbElems& aResMap)
+{
+  MESSAGE("StdMeshers_MEFISTO_2D::Evaluate");
+
+  TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
+
+  double aLen = 0.0;
+  double NbSeg = 0;
+  bool IsQuadratic = false;
+  bool IsFirst = true;
+  TopExp_Explorer exp(F,TopAbs_EDGE);
+  for(; exp.More(); exp.Next()) {
+    TopoDS_Edge E = TopoDS::Edge(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find( aMesh.GetSubMesh(E) );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    int nbe = Max(aVec[1],aVec[2]);
+    NbSeg += nbe;
+    if(IsFirst) {
+      IsQuadratic = ( aVec[2] > aVec[1] );
+      IsFirst = false;
+    }
+    double a,b;
+    TopLoc_Location L;
+    Handle(Geom_Curve) C = BRep_Tool::Curve(E,L,a,b);
+    gp_Pnt P1;
+    C->D0(a,P1);
+    double dp = (b-a)/nbe;
+    for(int i=1; i<=nbe; i++) {
+      gp_Pnt P2;
+      C->D0(a+i*dp,P2);
+      aLen += P1.Distance(P2);
+      P1 = P2;
+    }
+  }
+  aLen = aLen/NbSeg; // middle length
+
+  _edgeLength = DBL_MAX;
+  double tmpLength = Min( _edgeLength, aLen );
+
+  GProp_GProps G;
+  BRepGProp::SurfaceProperties(aShape,G);
+  double anArea = G.Mass();
+
+  int nbFaces = (int) anArea/(tmpLength*tmpLength*sqrt(3)/4);
+  int nbNodes = (int) ( nbFaces*3 - (NbSeg-1)*2 ) / 6;
+
+  std::vector<int> aVec(17);
+  for(int i=0; i<17; i++) aVec[i] = 0;
+  if(IsQuadratic) {
+    aVec[4] = nbFaces;
+    aVec[0] = nbNodes + nbFaces*3 - (NbSeg-1);
+  }
+  else {
+    aVec[0] = nbNodes;
+    aVec[3] = nbFaces;
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=======================================================================
 //function : fixOverlappedLinkUV
 //purpose  : prevent failure due to overlapped adjacent links
index fba4b2d3480daf6099a4011f57802cf70f80317e..73075dc0749aa2da5b4f9626f25296bdde6bb186 100644 (file)
@@ -57,6 +57,9 @@ public:
   virtual bool Compute(SMESH_Mesh& aMesh,
                       const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   typedef boost::shared_ptr< StdMeshers_FaceSide> StdMeshers_FaceSidePtr;
   typedef std::vector< StdMeshers_FaceSidePtr > TWireVector;
 
index 3ff7db018d29e5499a1d20906f5b195f4e756bd3..5e85ce9e1b176a62b7ac5da2420f1c03f9840e9b 100644 (file)
@@ -46,6 +46,8 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Shell.hxx>
@@ -1882,3 +1884,100 @@ const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID)
 }
 
 
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+bool StdMeshers_Penta_3D::Evaluate(SMESH_Mesh& aMesh, 
+                                  const TopoDS_Shape& aShape,
+                                  MapShapeNbElems& aResMap)
+{
+  MESSAGE("StdMeshers_Penta_3D::Evaluate()");
+
+  // find face contains only triangles
+  vector < SMESH_subMesh * >meshFaces;
+  TopTools_SequenceOfShape aFaces;
+  int NumBase = 0, i = 0;
+  for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+    i++;
+    aFaces.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    meshFaces.push_back(aSubMesh);
+    MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
+    std::vector<int> aVec = (*anIt).second;
+    int nbtri = Max(aVec[3],aVec[4]);
+    int nbqua = Max(aVec[5],aVec[6]);
+    if( nbtri>0 && nbqua==0 ) {
+      NumBase = i;
+    }
+  }
+
+  if(NumBase==0) return false;
+
+  // find number of 1d elems for base face
+  int nb1d = 0;
+  TopTools_MapOfShape Edges1;
+  for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) {
+    Edges1.Add(exp.Current());
+    SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb1d += Max(aVec[1],aVec[2]);
+    }
+  }
+  // find face opposite to base face
+  int OppNum = 0;
+  for(i=1; i<=6; i++) {
+    if(i==NumBase) continue;
+    bool IsOpposite = true;
+    for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+      if( Edges1.Contains(exp.Current()) ) {
+       IsOpposite = false;
+       break;
+      }
+    }
+    if(IsOpposite) {
+      OppNum = i;
+      break;
+    }
+  }
+  // find number of 2d elems on side faces
+  int nb2d = 0;
+  for(i=1; i<=6; i++) {
+    if( i==OppNum || i==NumBase ) continue;
+    MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    nb2d += Max(aVec[5],aVec[6]);
+  }
+  
+  MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] );
+  std::vector<int> aVec = (*anIt).second;
+  int nb2d_face0 = Max(aVec[5],aVec[6]);
+  int nb0d_face0 = aVec[0];
+
+  anIt = aResMap.find( meshFaces[OppNum-1] );
+  for(i=0; i<17; i++)
+    (*anIt).second[i] = aVec[i];
+
+  SMESH_MesherHelper aTool (aMesh);
+  bool _quadraticMesh = aTool.IsQuadraticSubMesh(aShape);
+
+  std::vector<int> aResVec(17);
+  for(int i=0; i<17; i++) aResVec[i] = 0;
+  if(_quadraticMesh) {
+    aResVec[13] = nb2d_face0 * ( nb2d/nb1d );
+    aResVec[0] = nb0d_face0 * ( 2*nb2d/nb1d - 1 );
+  }
+  else {
+    aResVec[0] = nb0d_face0 * ( nb2d/nb1d - 1 );
+    aResVec[12] = nb2d_face0 * ( nb2d/nb1d );
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
+
index f061f81443a5f2e8b21c9e1ba93d3c0e000bbaba..882c3b4f3441204f52f7cc147a1f30348e603aa9 100644 (file)
@@ -45,6 +45,7 @@
 #include "SMESH_Block.hxx"
 #include "SMESH_ComputeError.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_3D_Algo.hxx"
 
 typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
 
@@ -204,6 +205,9 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D {
     // The key of theIJNodes map is a normalized parameter of each
     // 0-the node on theBaseEdge.
 
+    bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                 MapShapeNbElems& aResMap);
+
 
   protected: // methods
     
index 6374868c14347f9054695751f269f586eaab9210..41657596df51d63b4e4263b8db56c8c340f30b66 100644 (file)
@@ -42,6 +42,8 @@
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
 
 using namespace std;
@@ -366,6 +368,115 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Prism_3D::Evaluate(SMESH_Mesh& theMesh,
+                                  const TopoDS_Shape& theShape,
+                                  MapShapeNbElems& aResMap)
+{
+  // find face contains only triangles
+  vector < SMESH_subMesh * >meshFaces;
+  TopTools_SequenceOfShape aFaces;
+  int NumBase = 0, i = 0, NbQFs = 0;
+  for (TopExp_Explorer exp(theShape, TopAbs_FACE); exp.More(); exp.Next()) {
+    i++;
+    aFaces.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = theMesh.GetSubMesh(exp.Current());
+    meshFaces.push_back(aSubMesh);
+    MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i-1]);
+    std::vector<int> aVec = (*anIt).second;
+    int nbtri = Max(aVec[3],aVec[4]);
+    int nbqua = Max(aVec[5],aVec[6]);
+    if( nbtri==0 && nbqua>0 ) {
+      NbQFs++;
+    }
+    if( nbtri>0 ) {
+      NumBase = i;
+    }
+  }
+
+  if(NbQFs<4) {
+    std::vector<int> aResVec(17);
+    for(int i=0; i<17; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  if(NumBase==0) NumBase = 1; // only quads => set 1 faces as base
+
+  // find number of 1d elems for base face
+  int nb1d = 0;
+  TopTools_MapOfShape Edges1;
+  for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) {
+    Edges1.Add(exp.Current());
+    SMESH_subMesh *sm = theMesh.GetSubMesh(exp.Current());
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb1d += Max(aVec[1],aVec[2]);
+    }
+  }
+  // find face opposite to base face
+  int OppNum = 0;
+  for(i=1; i<=6; i++) {
+    if(i==NumBase) continue;
+    bool IsOpposite = true;
+    for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+      if( Edges1.Contains(exp.Current()) ) {
+       IsOpposite = false;
+       break;
+      }
+    }
+    if(IsOpposite) {
+      OppNum = i;
+      break;
+    }
+  }
+  // find number of 2d elems on side faces
+  int nb2d = 0;
+  for(i=1; i<=6; i++) {
+    if( i==OppNum || i==NumBase ) continue;
+    MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    nb2d += Max(aVec[5],aVec[6]);
+  }
+  
+  MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] );
+  std::vector<int> aVec = (*anIt).second;
+  bool IsQuadratic = (aVec[4]>aVec[3]) || (aVec[6]>aVec[5]);
+  int nb2d_face0_3 = Max(aVec[3],aVec[4]);
+  int nb2d_face0_4 = Max(aVec[5],aVec[6]);
+  int nb0d_face0 = aVec[0];
+  int nb1d_face0_int = ( nb2d_face0_3*3 + nb2d_face0_4*4 - nb1d ) / 2;
+
+  std::vector<int> aResVec(17);
+  for(int i=0; i<17; i++) aResVec[i] = 0;
+  if(IsQuadratic) {
+    aResVec[13] = nb2d_face0_3 * ( nb2d/nb1d );
+    aResVec[15] = nb2d_face0_4 * ( nb2d/nb1d );
+    aResVec[0] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+  }
+  else {
+    aResVec[0] = nb0d_face0 * ( nb2d/nb1d - 1 );
+    aResVec[12] = nb2d_face0_3 * ( nb2d/nb1d );
+    aResVec[14] = nb2d_face0_4 * ( nb2d/nb1d );
+  }
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
+
+
 //================================================================================
 /*!
  * \brief Create prisms
index 5c29f63ecce41c06f28bc0b09c0e7d669415e857..d258bb43288e3e406a0d328aa82b4ae33e159689 100644 (file)
@@ -379,6 +379,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Enable removal of quadrangles from the bottom face and
    * triangles creation there by projection from the top
index 4fd7c5d8dc9c5fd0192e4b16a1f3ed5653b9173b..1cb6e21f60cbb39a3e75911475237f10a460356c 100644 (file)
@@ -372,6 +372,97 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_1D::Evaluate(SMESH_Mesh& theMesh,
+                                       const TopoDS_Shape& theShape,
+                                       MapShapeNbElems& aResMap)
+{
+  if ( !_sourceHypo )
+    return false;
+
+  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); 
+  SMESH_Mesh * tgtMesh = & theMesh;
+  if ( !srcMesh )
+    srcMesh = tgtMesh;
+
+  SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+
+  // ---------------------------
+  // Make subshapes association
+  // ---------------------------
+
+  TopoDS_Edge srcEdge, tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD));
+  TopoDS_Shape srcShape = _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD);
+
+  TAssocTool::TShapeShapeMap shape2ShapeMap;
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtEdge );
+  if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcShape, srcMesh,
+                                             shape2ShapeMap) ||
+       !shape2ShapeMap.IsBound( tgtEdge ))
+    return error("Vertices association failed" );
+
+  srcEdge = TopoDS::Edge( shape2ShapeMap( tgtEdge ).Oriented(TopAbs_FORWARD));
+//   cout << " srcEdge #" << srcMesh->GetMeshDS()->ShapeToIndex( srcEdge )
+//        << " tgtEdge #" << tgtMesh->GetMeshDS()->ShapeToIndex( tgtEdge ) << endl;
+
+  TopoDS_Vertex tgtV[2], srcV[2];
+  TopExp::Vertices( tgtEdge, tgtV[0], tgtV[1] );
+  TopExp::Vertices( srcEdge, srcV[0], srcV[1] );
+
+  // ----------------------------------------------
+  // Assure that mesh on a source edge is computed
+  // ----------------------------------------------
+
+  SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcEdge );
+  //SMESH_subMesh* tgtSubMesh = tgtMesh->GetSubMesh( tgtEdge );
+
+  if ( tgtMesh == srcMesh ) {
+    if ( !TAssocTool::MakeComputed( srcSubMesh ))
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+  }
+  else {
+    if ( !srcSubMesh->IsMeshComputed() )
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+  }
+  // -----------------------------------------------
+  // Find out nodes distribution on the source edge
+  // -----------------------------------------------
+
+  double srcLength = EdgeLength( srcEdge );
+  double tgtLength = EdgeLength( tgtEdge );
+  
+  vector< double > params; // sorted parameters of nodes on the source edge
+  if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params ))
+    return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge");
+
+  int nbNodes = params.size();
+
+  std::vector<int> aVec(17);
+  for(int i=0; i<17; i++) aVec[i] = 0;
+
+  aVec[0] = nbNodes;
+
+  bool quadratic = false;
+  SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+  if ( elemIt->more() )
+    quadratic = elemIt->next()->IsQuadratic();
+  if(quadratic)
+    aVec[2] = (nbNodes-1)/2;
+  else
+    aVec[1] = nbNodes - 1;
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  * \brief Sets a default event listener to submesh of the source edge
index 52f76e17043fda139be494ea44746949207a28ef..be003ed7b6db9d4c33f088800c072fa5f0cd72b6 100644 (file)
@@ -46,6 +46,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Sets a default event listener to submesh of the source edge
    *  \param whenSetToSubMesh - submesh where algo is set
index 3457197f5baff75364d1cd9f07c8fe38789b40f5..682c16bb52f0712681e2f6c3a0f9c524cda7c5ee 100644 (file)
@@ -642,6 +642,83 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_2D::Evaluate(SMESH_Mesh& theMesh,
+                                       const TopoDS_Shape& theShape,
+                                       MapShapeNbElems& aResMap)
+{
+  if ( !_sourceHypo )
+    return false;
+
+  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+  SMESH_Mesh * tgtMesh = & theMesh;
+  if ( !srcMesh )
+    srcMesh = tgtMesh;
+
+  // ---------------------------
+  // Make subshapes association
+  // ---------------------------
+
+  TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD));
+  TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD);
+
+  TAssocTool::TShapeShapeMap shape2ShapeMap;
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtFace );
+  if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh,
+                                             shape2ShapeMap)  ||
+       !shape2ShapeMap.IsBound( tgtFace ))
+    return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
+
+  TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
+
+  // ----------------------------------------------
+  // Assure that mesh on a source Face is computed
+  // ----------------------------------------------
+
+  SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcFace );
+
+  if ( !srcSubMesh->IsMeshComputed() )
+    return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+
+
+  std::vector<int> aVec(17);
+  for(int i=0; i<17; i++) aVec[i] = 0;
+
+  aVec[0] = srcSubMesh->GetSubMeshDS()->NbNodes();
+
+  //bool quadratic = false;
+  SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+  while ( elemIt->more() ) {
+    const SMDS_MeshElement* E  = elemIt->next();
+    if( E->NbNodes()==3 ) {
+      aVec[3]++;
+    }
+    else if( E->NbNodes()==4 ) {
+      aVec[5]++;
+    }
+    else if( E->NbNodes()==6 && E->IsQuadratic() ) {
+      aVec[4]++;
+    }
+    else if( E->NbNodes()==8 && E->IsQuadratic() ) {
+      aVec[6]++;
+    }
+    else {
+      aVec[7]++;
+    }
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  * \brief Sets a default event listener to submesh of the source face
index 006db83448d5da5e6a95a278bd097ffa6eda0231..26506e81a7f513b3d5703b1bf596418e138f7998 100644 (file)
@@ -44,6 +44,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Sets a default event listener to submesh of the source face
    *  \param whenSetToSubMesh - submesh where algo is set
index 86d6d65d3d5e5d639009dd86493dc946dd3a65a1..6281024106e9d0c896a24bfa764b572d27823432 100644 (file)
@@ -420,6 +420,104 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_3D::Evaluate(SMESH_Mesh& aMesh,
+                                       const TopoDS_Shape& aShape,
+                                       MapShapeNbElems& aResMap)
+{
+  if ( !_sourceHypo )
+    return false;
+
+  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+  SMESH_Mesh * tgtMesh = & aMesh;
+  if ( !srcMesh )
+    srcMesh = tgtMesh;
+
+  // get shell from shape3D
+  TopoDS_Shell srcShell, tgtShell;
+  TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL );
+  int nbShell;
+  for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
+    srcShell = TopoDS::Shell( exp.Current() );
+  if ( nbShell != 1 )
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Source shape must have 1 shell but not ") << nbShell);
+
+  exp.Init( aShape, TopAbs_SHELL );
+  for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
+    tgtShell = TopoDS::Shell( exp.Current() );
+  if ( nbShell != 1 )
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Target shape must have 1 shell but not ") << nbShell);
+
+  // Check that shapes are blocks
+  if ( TAssocTool::Count( tgtShell, TopAbs_FACE , 1 ) != 6 ||
+       TAssocTool::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 ||
+       TAssocTool::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 )
+    return error(COMPERR_BAD_SHAPE, "Target shape is not a block");
+  if ( TAssocTool::Count( srcShell, TopAbs_FACE , 1 ) != 6 ||
+       TAssocTool::Count( srcShell, TopAbs_EDGE , 1 ) != 12 ||
+       TAssocTool::Count( srcShell, TopAbs_WIRE , 1 ) != 6 )
+    return error(COMPERR_BAD_SHAPE, "Source shape is not a block");
+
+  // Assure that mesh on a source shape is computed
+
+  SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
+
+  if ( !srcSubMesh->IsMeshComputed() )
+    return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+
+
+  std::vector<int> aVec(17);
+  for(int i=0; i<17; i++) aVec[i] = 0;
+
+  aVec[0] = srcSubMesh->GetSubMeshDS()->NbNodes();
+
+  //bool quadratic = false;
+  SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+  while ( elemIt->more() ) {
+    const SMDS_MeshElement* E  = elemIt->next();
+    if( E->NbNodes()==4 ) {
+      aVec[8]++;
+    }
+    else if( E->NbNodes()==5 ) {
+      aVec[10]++;
+    }
+    else if( E->NbNodes()==6 ) {
+      aVec[12]++;
+    }
+    else if( E->NbNodes()==8 ) {
+      aVec[14]++;
+    }
+    else if( E->NbNodes()==10 && E->IsQuadratic() ) {
+      aVec[9]++;
+    }
+    else if( E->NbNodes()==13 && E->IsQuadratic() ) {
+      aVec[11]++;
+    }
+    else if( E->NbNodes()==15 && E->IsQuadratic() ) {
+      aVec[13]++;
+    }
+    else if( E->NbNodes()==20 && E->IsQuadratic() ) {
+      aVec[15]++;
+    }
+    else {
+      aVec[16]++;
+    }
+  }
+
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  * \brief Sets a default event listener to submesh of the source shape
index 7f4200ef42d87ae6f8a0d4db2dc6d4915e423274..8f95545091bb015b60fa4c94b7eb311c77e67771 100644 (file)
@@ -44,6 +44,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Sets a default event listener to submesh of the source shape
    *  \param whenSetToSubMesh - submesh where algo is set
index acc8731860dbd6c0bf234d181f7b366565756d42..0a13e88eaedd7e10772f9dbadef611e1af4c7d16 100644 (file)
@@ -587,6 +587,90 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   return isOk;
 }
 
+
+//=============================================================================
+/*!
+ *  Evaluate
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh,
+                                        const TopoDS_Shape& aShape,
+                                       MapShapeNbElems& aResMap)
+
+{
+  aMesh.GetSubMesh(aShape);
+
+  std::vector<int> aNbNodes(4);
+  bool IsQuadratic = false;
+  if( !CheckNbEdgesForEvaluate( aMesh, aShape, aResMap, aNbNodes, IsQuadratic ) ) {
+    std::vector<int> aResVec(17);
+    for(int i=0; i<17; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  if(myQuadranglePreference) {
+    int n1 = aNbNodes[0];
+    int n2 = aNbNodes[1];
+    int n3 = aNbNodes[2];
+    int n4 = aNbNodes[3];
+    int nfull = n1+n2+n3+n4;
+    int ntmp = nfull/2;
+    ntmp = ntmp*2;
+    if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
+      // special path for using only quandrangle faces
+      return EvaluateQuadPref(aMesh, aShape, aNbNodes, aResMap, IsQuadratic);
+      //return true;
+    }
+  }
+
+  int nbdown  = aNbNodes[0];
+  int nbup    = aNbNodes[2];
+
+  int nbright = aNbNodes[1];
+  int nbleft  = aNbNodes[3];
+
+  int nbhoriz  = Min(nbdown, nbup);
+  int nbvertic = Min(nbright, nbleft);
+
+  int dh = Max(nbdown, nbup) - nbhoriz;
+  int dv = Max(nbright, nbleft) - nbvertic;
+
+  int kdh = 0;
+  if(dh>0) kdh = 1;
+  int kdv = 0;
+  if(dv>0) kdv = 1;
+
+  int nbNodes = (nbhoriz-2)*(nbvertic-2);
+  int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2;
+  if( kdh==1 && kdv==1 ) nbFaces3 -= 2;
+  int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv);
+
+  std::vector<int> aVec(17);
+  for(int i=0; i<17; i++) aVec[i] = 0;
+  if(IsQuadratic) {
+    aVec[4] = nbFaces3;
+    aVec[6] = nbFaces4;
+    int nbbndedges = nbdown + nbup + nbright + nbleft -4;
+    int nbintedges = ( nbFaces4*4 + nbFaces3*3 - nbbndedges ) / 2;
+    aVec[0] = nbNodes + nbintedges;
+  }
+  else {
+    aVec[0] = nbNodes;
+    aVec[3] = nbFaces3;
+    aVec[5] = nbFaces4;
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //================================================================================
 /*!
  * \brief Return true if only two given edges meat at their common vertex
@@ -721,6 +805,146 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMes
   return quad;
 }
 
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh,
+                                                      const TopoDS_Shape & aShape,
+                                                      MapShapeNbElems& aResMap,
+                                                      std::vector<int>& aNbNodes,
+                                                      bool& IsQuadratic)
+
+{
+  const TopoDS_Face & F = TopoDS::Face(aShape);
+
+  // verify 1 wire only, with 4 edges
+  TopoDS_Vertex V;
+  list< TopoDS_Edge > edges;
+  list< int > nbEdgesInWire;
+  int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+  if (nbWire != 1) {
+    return false;
+  }
+
+  aNbNodes.resize(4);
+
+  int nbSides = 0;
+  list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+  SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+  MapShapeNbElemsItr anIt = aResMap.find(sm);
+  if(anIt==aResMap.end()) {
+    return false;
+  }
+  std::vector<int> aVec = (*anIt).second;
+  IsQuadratic = (aVec[2] > aVec[1]);
+  if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
+    for(; edgeIt != edges.end(); edgeIt++) {
+      SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if(anIt==aResMap.end()) {
+       return false;
+      }
+      std::vector<int> aVec = (*anIt).second;
+      if(IsQuadratic)
+       aNbNodes[nbSides] = (aVec[0]-1)/2 + 2;
+      else
+       aNbNodes[nbSides] = aVec[0] + 2;
+      nbSides++;
+    }
+  }
+  else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+    list< TopoDS_Edge > sideEdges;
+    while ( !edges.empty()) {
+      sideEdges.clear();
+      sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+      bool sameSide = true;
+      while ( !edges.empty() && sameSide ) {
+        sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() );
+        if ( sameSide )
+          sideEdges.splice( sideEdges.end(), edges, edges.begin());
+      }
+      if ( nbSides == 0 ) { // go backward from the first edge
+        sameSide = true;
+        while ( !edges.empty() && sameSide ) {
+          sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() );
+          if ( sameSide )
+            sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+        }
+      }
+      list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+      aNbNodes[nbSides] = 1;
+      for(; ite!=sideEdges.end(); ite++) {
+       SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+       MapShapeNbElemsItr anIt = aResMap.find(sm);
+       if(anIt==aResMap.end()) {
+         return false;
+       }
+       std::vector<int> aVec = (*anIt).second;
+       if(IsQuadratic)
+         aNbNodes[nbSides] += (aVec[0]-1)/2 + 1;
+       else
+         aNbNodes[nbSides] += aVec[0] + 1;
+      }
+      ++nbSides;
+    }
+    // issue 20222. Try to unite only edges shared by two same faces
+    if (nbSides < 4) {
+      nbSides = 0;
+      SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+      while ( !edges.empty()) {
+        sideEdges.clear();
+        sideEdges.splice( sideEdges.end(), edges, edges.begin());
+        bool sameSide = true;
+        while ( !edges.empty() && sameSide ) {
+          sameSide =
+            SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) &&
+            twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh );
+          if ( sameSide )
+            sideEdges.splice( sideEdges.end(), edges, edges.begin());
+        }
+        if ( nbSides == 0 ) { // go backward from the first edge
+          sameSide = true;
+          while ( !edges.empty() && sameSide ) {
+            sameSide =
+              SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) &&
+              twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh );
+            if ( sameSide )
+              sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+          }
+        }
+       list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+       aNbNodes[nbSides] = 1;
+       for(; ite!=sideEdges.end(); ite++) {
+         SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+         MapShapeNbElemsItr anIt = aResMap.find(sm);
+         if(anIt==aResMap.end()) {
+           return false;
+         }
+         std::vector<int> aVec = (*anIt).second;
+         if(IsQuadratic)
+           aNbNodes[nbSides] += (aVec[0]-1)/2 + 1;
+         else
+           aNbNodes[nbSides] += aVec[0] + 1;
+       }
+        ++nbSides;
+      }
+    }
+  }
+  if (nbSides != 4) {
+    if ( !nbSides )
+      nbSides = nbEdgesInWire.front();
+    error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
+    return false;
+  }
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  *  CheckAnd2Dcompute
@@ -1397,8 +1621,10 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
 
       }
     }
+    int nbf=0;
     for(j=1; j<nnn-1; j++) {
       for(i=1; i<nb; i++) {
+       nbf++;
         if(WisF) {
           SMDS_MeshFace* F =
             myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j),
@@ -1413,7 +1639,6 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         }
       }
     }
-
     int drl = abs(nr-nl);
     // create faces for region C
     StdMeshers_Array2OfNode NodesC(1,nb,1,drl+1+addv);
@@ -1512,6 +1737,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
       // create faces
       for(j=1; j<=drl+addv; j++) {
         for(i=1; i<nb; i++) {
+         nbf++;
           if(WisF) {
             SMDS_MeshFace* F =
               myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
@@ -1545,6 +1771,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         NodesLast.SetValue(nnn,1,NodesC.Value(nb,i));
       }
       for(i=1; i<nt; i++) {
+       nbf++;
         if(WisF) {
           SMDS_MeshFace* F =
             myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1),
@@ -1566,6 +1793,132 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
   return isOk;
 }
 
+
+//=======================================================================
+/*!
+ * Evaluate only quandrangle faces
+ */
+//=======================================================================
+
+bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh &        aMesh,
+                                                const TopoDS_Shape& aShape,
+                                                std::vector<int>& aNbNodes,
+                                               MapShapeNbElems& aResMap,
+                                               bool IsQuadratic)
+{
+  // Auxilary key in order to keep old variant
+  // of meshing after implementation new variant
+  // for bug 0016220 from Mantis.
+  bool OldVersion = false;
+
+  const TopoDS_Face& F = TopoDS::Face(aShape);
+  Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+
+  int nb = aNbNodes[0];
+  int nr = aNbNodes[1];
+  int nt = aNbNodes[2];
+  int nl = aNbNodes[3];
+  int dh = abs(nb-nt);
+  int dv = abs(nr-nl);
+
+  if( dh>=dv ) {
+    if( nt>nb ) {
+      // it is a base case => not shift 
+    }
+    else {
+      // we have to shift on 2
+      nb = aNbNodes[2];
+      nr = aNbNodes[3];
+      nt = aNbNodes[0];
+      nl = aNbNodes[1];
+    }
+  }
+  else {
+    if( nr>nl ) {
+      // we have to shift quad on 1
+      nb = aNbNodes[3];
+      nr = aNbNodes[0];
+      nt = aNbNodes[1];
+      nl = aNbNodes[2];
+    }
+    else {
+      // we have to shift quad on 3
+      nb = aNbNodes[1];
+      nr = aNbNodes[2];
+      nt = aNbNodes[3];
+      nl = aNbNodes[0];
+    }
+  }
+
+  dh = abs(nb-nt);
+  dv = abs(nr-nl);
+  int nbh  = Max(nb,nt);
+  int nbv = Max(nr,nl);
+  int addh = 0;
+  int addv = 0;
+
+  if(dh>dv) {
+    addv = (dh-dv)/2;
+    nbv = nbv + addv;
+  }
+  else { // dv>=dh
+    addh = (dv-dh)/2;
+    nbh = nbh + addh;
+  }
+
+  int dl,dr;
+  if(OldVersion) {
+    // add some params to right and left after the first param
+    // insert to right
+    dr = nbv - nr;
+    // insert to left
+    dl = nbv - nl;
+  }
+  
+  int nnn = Min(nr,nl);
+
+  int nbNodes = 0;
+  int nbFaces = 0;
+  if(OldVersion) {
+    // step1: create faces for left domain
+    if(dl>0) {
+      nbNodes += dl*(nl-1);
+      nbFaces += dl*(nl-1);
+    }
+    // step2: create faces for right domain
+    if(dr>0) {
+      nbNodes += dr*(nr-1);
+      nbFaces += dr*(nr-1);
+    }
+    // step3: create faces for central domain
+    nbNodes += (nb-2)*(nnn-1) + (nbv-nnn-1)*(nb-2);
+    nbFaces += (nb-1)*(nbv-1);
+  }
+  else { // New version (!OldVersion)
+    nbNodes += (nnn-2)*(nb-2);
+    nbFaces += (nnn-2)*(nb-1);
+    int drl = abs(nr-nl);
+    nbNodes += drl*(nb-1) + addv*nb;
+    nbFaces += (drl+addv)*(nb-1) + (nt-1);
+  } // end new version implementation
+
+  std::vector<int> aVec(17);
+  for(int i=0; i<17; i++) aVec[i] = 0;
+  if(IsQuadratic) {
+    aVec[6] = nbFaces;
+    aVec[0] = nbNodes + nbFaces*4;
+  }
+  else {
+    aVec[0] = nbNodes;
+    aVec[5] = nbFaces;
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*! Split quadrangle in to 2 triangles by smallest diagonal
  *   
index 18c1daeca8183eac0a60275544a92622b1d96c3e..6c26fde4a0f671154efaf04834c7a7afbced428a 100644 (file)
@@ -65,6 +65,9 @@ public:
   virtual bool Compute(SMESH_Mesh& aMesh,
                       const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh,
                                    const TopoDS_Shape& aShape,
                                     const bool CreateQuadratic);
@@ -74,6 +77,12 @@ protected:
   FaceQuadStruct* CheckNbEdges(SMESH_Mesh& aMesh,
                                const TopoDS_Shape& aShape);
 
+  bool CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh,
+                              const TopoDS_Shape & aShape,
+                              MapShapeNbElems& aResMap,
+                              std::vector<int>& aNbNodes,
+                               bool& IsQuadratic);
+
   bool SetNormalizedGrid(SMESH_Mesh& aMesh,
                         const TopoDS_Shape& aShape,
                         FaceQuadStruct*& quad);
@@ -89,10 +98,15 @@ protected:
    * Special function for creation only quandrangle faces
    */
   bool ComputeQuadPref(SMESH_Mesh& aMesh,
-                       
                        const TopoDS_Shape& aShape,
                        FaceQuadStruct* quad);
 
+  bool EvaluateQuadPref(SMESH_Mesh& aMesh,
+                       const TopoDS_Shape& aShape,
+                       std::vector<int>& aNbNodes,
+                       MapShapeNbElems& aResMap,
+                        bool IsQuadratic);
+
   UVPtStruct* LoadEdgePoints2(SMESH_Mesh& aMesh,
                              const TopoDS_Face& F, const TopoDS_Edge& E,
                               bool IsReverse);
index 133b681605cf78bb6974bf289625666d0856d809..182798c941b9474198019ae80f2e7851cc671597 100644 (file)
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Solid.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <gp.hxx>
 #include <gp_Pnt.hxx>
 
@@ -386,3 +388,171 @@ bool StdMeshers_RadialPrism_3D::computeLayerPositions(const gp_Pnt& pIn,
   }
   RETURN_BAD_RESULT("Bad hypothesis");
 }
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh,
+                                        const TopoDS_Shape& aShape,
+                                        MapShapeNbElems& aResMap)
+{
+  // get 2 shells
+  TopoDS_Solid solid = TopoDS::Solid( aShape );
+  TopoDS_Shell outerShell = BRepTools::OuterShell( solid );
+  TopoDS_Shape innerShell;
+  int nbShells = 0;
+  for ( TopoDS_Iterator It (solid); It.More(); It.Next(), ++nbShells )
+    if ( !outerShell.IsSame( It.Value() ))
+      innerShell = It.Value();
+  if ( nbShells != 2 ) {
+    std::vector<int> aResVec(17);
+    for(int i=0; i<17; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  // Associate subshapes of the shells
+  TAssocTool::TShapeShapeMap shape2ShapeMap;
+  if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
+                                             innerShell, &aMesh,
+                                             shape2ShapeMap) ) {
+    std::vector<int> aResVec(17);
+    for(int i=0; i<17; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  // get info for outer shell
+  int nb0d_Out=0, nb2d_3_Out=0, nb2d_4_Out=0;
+  //TopTools_SequenceOfShape FacesOut;
+  for (TopExp_Explorer exp(outerShell, TopAbs_FACE); exp.More(); exp.Next()) {
+    //FacesOut.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_Out += aVec[0];
+    nb2d_3_Out += Max(aVec[3],aVec[4]);
+    nb2d_4_Out += Max(aVec[5],aVec[6]);
+  }
+  int nb1d_Out = 0;
+  TopTools_MapOfShape tmpMap;
+  for (TopExp_Explorer exp(outerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_Out += aVec[0];
+    nb1d_Out += Max(aVec[1],aVec[2]);
+  }
+  tmpMap.Clear();
+  for (TopExp_Explorer exp(outerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    nb0d_Out++;
+  }
+
+  // get info for inner shell
+  int nb0d_In=0, nb2d_3_In=0, nb2d_4_In=0;
+  //TopTools_SequenceOfShape FacesIn;
+  for (TopExp_Explorer exp(innerShell, TopAbs_FACE); exp.More(); exp.Next()) {
+    //FacesIn.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_In += aVec[0];
+    nb2d_3_In += Max(aVec[3],aVec[4]);
+    nb2d_4_In += Max(aVec[5],aVec[6]);
+  }
+  int nb1d_In = 0;
+  tmpMap.Clear();
+  bool IsQuadratic = false;
+  bool IsFirst = true;
+  for (TopExp_Explorer exp(innerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_In += aVec[0];
+    nb1d_In += Max(aVec[1],aVec[2]);
+    if(IsFirst) {
+      IsQuadratic = (aVec[2] > aVec[1]);
+      IsFirst = false;
+    }
+  }
+  tmpMap.Clear();
+  for (TopExp_Explorer exp(innerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    nb0d_In++;
+  }
+
+  bool IsOK = (nb0d_Out==nb0d_In) && (nb1d_Out==nb1d_In) && 
+              (nb2d_3_Out==nb2d_3_In) && (nb2d_4_Out==nb2d_4_In);
+  if(!IsOK) {
+    std::vector<int> aResVec(17);
+    for(int i=0; i<17; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  int nbLayers = 0;
+  if( myNbLayerHypo ) {
+    nbLayers = myNbLayerHypo->GetNumberOfLayers();
+  }
+  if ( myDistributionHypo ) {
+    if ( !myDistributionHypo->GetLayerDistribution() ) {
+      std::vector<int> aResVec(17);
+      for(int i=0; i<17; i++) aResVec[i] = 0;
+      SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+      aResMap.insert(std::make_pair(sm,aResVec));
+      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+      return false;
+    }
+    TopExp_Explorer exp(outerShell, TopAbs_VERTEX);
+    TopoDS_Vertex Vout = TopoDS::Vertex(exp.Current());
+    TopoDS_Vertex Vin = TopoDS::Vertex( shape2ShapeMap(Vout) );
+    if ( myLayerPositions.empty() ) {
+      gp_Pnt pIn = BRep_Tool::Pnt(Vin);
+      gp_Pnt pOut = BRep_Tool::Pnt(Vout);
+      computeLayerPositions( pIn, pOut );
+    }
+    nbLayers = myLayerPositions.size() + 1;
+  }
+
+  std::vector<int> aResVec(17);
+  for(int i=0; i<17; i++) aResVec[i] = 0;
+  if(IsQuadratic) {
+    aResVec[13] = nb2d_3_Out * nbLayers;
+    aResVec[15] = nb2d_4_Out * nbLayers;
+    int nb1d = ( nb2d_3_Out*3 + nb2d_4_Out*4 ) / 2;
+    aResVec[0] = nb0d_Out * ( 2*nbLayers - 1 ) - nb1d * nbLayers;
+  }
+  else {
+    aResVec[0] = nb0d_Out * ( nbLayers - 1 );
+    aResVec[12] = nb2d_3_Out * nbLayers;
+    aResVec[14] = nb2d_4_Out * nbLayers;
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
index d0c78352216509e4d7d2a5a8c50d9e0e2b834bc9..21d8f8362fdcc4c1ae6249d9a20f6d5c4b566c6c 100644 (file)
@@ -51,6 +51,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
 protected:
 
   typedef std::vector<const SMDS_MeshNode* >            TNodeColumn;
index ee4aa86e78a1e992e97c3c2a599a9ef13b4105d3..6edeeb03664f7713dc0e0b7bc7bc376933d6befd 100644 (file)
@@ -930,6 +930,85 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
   return true;
 }
 
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
+                                    const TopoDS_Shape & theShape,
+                                    MapShapeNbElems& aResMap)
+{
+  if ( _hypType == NONE )
+    return false;
+
+  SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+
+  const TopoDS_Edge & EE = TopoDS::Edge(theShape);
+  TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
+  int shapeID = meshDS->ShapeToIndex( E );
+
+  double f, l;
+  Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
+
+  TopoDS_Vertex VFirst, VLast;
+  TopExp::Vertices(E, VFirst, VLast);   // Vfirst corresponds to f and Vlast to l
+
+  ASSERT(!VFirst.IsNull());
+  ASSERT(!VLast.IsNull());
+
+  std::vector<int> aVec(17);
+  for(int i=0; i<17; i++) aVec[i] = 0;
+
+  if (!Curve.IsNull()) {
+    list< double > params;
+    bool reversed = false;
+    if ( !_mainEdge.IsNull() )
+      reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
+
+    BRepAdaptor_Curve C3d( E );
+    double length = EdgeLength( E );
+    if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) {
+      SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+      aResMap.insert(std::make_pair(sm,aVec));
+      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+      return false;
+    }
+    redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast );
+
+    if(_quadraticMesh) {
+      aVec[0] = 2*params.size() + 1;
+      aVec[2] = params.size() + 1;
+    }
+    else {
+      aVec[0] = params.size();
+      aVec[1] = params.size() + 1;
+    }
+    
+  }
+  else {
+    //MESSAGE("************* Degenerated edge! *****************");
+    // Edge is a degenerated Edge : We put n = 5 points on the edge.
+    if(_quadraticMesh) {
+      aVec[0] = 11;
+      aVec[2] = 6;
+    }
+    else {
+      aVec[0] = 5;
+      aVec[1] = 6;
+    }
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  *  See comments in SMESH_Algo.cxx
index 7df8e45338f84c17f8445379e69fd81c428640a6..244ebe6a1b203935b981f72fe0d8b1041dd8f2a2 100644 (file)
@@ -49,6 +49,9 @@ public:
   virtual bool Compute(SMESH_Mesh& aMesh,
                       const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   virtual const std::list <const SMESHDS_Hypothesis *> &
     GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
 
index 60ba2518d71baede09a713eb761a42ed686c6643..20490932030186d40c1de548f7b6e636636cfd62 100644 (file)
@@ -92,3 +92,18 @@ bool StdMeshers_SegmentAroundVertex_0D::Compute(SMESH_Mesh&, const TopoDS_Shape&
   // StdMeshers_SegmentLengthAroundVertex hypothesis
   return true;
 }
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_SegmentAroundVertex_0D::Evaluate(SMESH_Mesh&,
+                                                const TopoDS_Shape&,
+                                                MapShapeNbElems&)
+{
+  // This algorithm exists in order just to enable assignation of
+  // StdMeshers_SegmentLengthAroundVertex hypothesis
+  return false;
+}
index 4054a715d5c31c84909b0c7a7cf7086a521909f4..a2f1bd579b5f994752c9a94218a27207a2d35fa5 100644 (file)
@@ -46,6 +46,8 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 };
 
 #endif
index e44345af42877cd5efe6020977b870fce7c3eb14..3638498e138808b16cceb5a002bc3109a876e8df 100644 (file)
@@ -60,10 +60,27 @@ bool StdMeshers_UseExisting_1D::CheckHypothesis(SMESH_Mesh& ,
 
 bool StdMeshers_UseExisting_1D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
 {
-  // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode
+  // This algorithm exists to allow mesh generation by mesh
+  // edition functions in TUI mode
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_UseExisting_1D::Evaluate(SMESH_Mesh&,
+                                        const TopoDS_Shape&,
+                                        MapShapeNbElems&)
+{
+  // This algorithm exists to allow mesh generation by mesh
+  // edition functions in TUI mode
+  return false;
+}
+
+
 //=======================================================================
 //function : StdMeshers_UseExisting_2D
 //purpose  : 
@@ -97,6 +114,22 @@ bool StdMeshers_UseExisting_2D::CheckHypothesis(SMESH_Mesh& ,
 
 bool StdMeshers_UseExisting_2D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
 {
-  // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode
+  // This algorithm exists to allow mesh generation by mesh edition
+  // functions in TUI mode
   return true;
 }
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_UseExisting_2D::Evaluate(SMESH_Mesh&,
+                                        const TopoDS_Shape&,
+                                        MapShapeNbElems&)
+{
+  // This algorithm exists to allow mesh generation by mesh edition
+  // functions in TUI mode
+  return false;
+}
index 6d5a5e495be4610b43b02a89868181fb03855530..961fb4ba9605e22a2e6fc10f7cbe7ee8983dabec 100644 (file)
@@ -46,6 +46,8 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 };
 
 class STDMESHERS_EXPORT StdMeshers_UseExisting_1D: public SMESH_1D_Algo
@@ -59,6 +61,8 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 };
 
 #endif