Salome HOME
23076: [CEA 1499] Get in python all sub-shapes in error after Compute
[modules/smesh.git] / src / StdMeshers / StdMeshers_Regular_1D.cxx
index f3449e85df61d1926df7074cbec8d7d107dbb9dc..73f11aff59838b56942fbddde96630ed2ad443a3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -68,6 +68,7 @@
 #include <limits>
 
 using namespace std;
+using namespace StdMeshers;
 
 //=============================================================================
 /*!
@@ -112,7 +113,7 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D()
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
@@ -127,13 +128,18 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh&         aMesh,
   const list <const SMESHDS_Hypothesis * > & hyps =
     GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false);
 
+  const SMESH_HypoFilter & propagFilter = StdMeshers_Propagation::GetFilter();
+
   // find non-auxiliary hypothesis
   const SMESHDS_Hypothesis *theHyp = 0;
+  set< string > propagTypes;
   list <const SMESHDS_Hypothesis * >::const_iterator h = hyps.begin();
   for ( ; h != hyps.end(); ++h ) {
     if ( static_cast<const SMESH_Hypothesis*>(*h)->IsAuxiliary() ) {
       if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 )
         _quadraticMesh = true;
+      if ( propagFilter.IsOk( static_cast< const SMESH_Hypothesis*>( *h ), aShape ))
+        propagTypes.insert( (*h)->GetName() );
     }
     else {
       if ( !theHyp )
@@ -293,11 +299,48 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh&         aMesh,
     ASSERT(_adaptiveHyp);
     _hypType = ADAPTIVE;
     _onlyUnaryInput = false;
+    aStatus = SMESH_Hypothesis::HYP_OK;
   }
   else
+  {
     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+  }
+
+  if ( propagTypes.size() > 1 && aStatus == HYP_OK )
+  {
+    // detect concurrent Propagation hyps
+    _usedHypList.clear();
+    list< TopoDS_Shape > assignedTo;
+    if ( aMesh.GetHypotheses( aShape, propagFilter, _usedHypList, true, &assignedTo ) > 1 )
+    {
+      // find most simple shape and a hyp on it
+      int simpleShape = TopAbs_COMPOUND;
+      const SMESHDS_Hypothesis* localHyp = 0;
+      list< TopoDS_Shape >::iterator            shape = assignedTo.begin();
+      list< const SMESHDS_Hypothesis *>::iterator hyp = _usedHypList.begin();
+      for ( ; shape != assignedTo.end(); ++shape )
+        if ( shape->ShapeType() > simpleShape )
+        {
+          simpleShape = shape->ShapeType();
+          localHyp = (*hyp);
+        }
+      // check if there a different hyp on simpleShape
+      shape = assignedTo.begin();
+      hyp = _usedHypList.begin();
+      for ( ; hyp != _usedHypList.end(); ++hyp, ++shape )
+        if ( shape->ShapeType() == simpleShape &&
+             !localHyp->IsSameName( **hyp ))
+        {
+          aStatus = HYP_INCOMPAT_HYPS;
+          return error( SMESH_Comment("Hypotheses of both \"")
+                        << StdMeshers_Propagation::GetName() << "\" and \""
+                        << StdMeshers_PropagOfDistribution::GetName()
+                        << "\" types can't be applied to the same edge");
+        }
+    }
+  }
 
-  return ( _hypType != NONE );
+  return ( aStatus == SMESH_Hypothesis::HYP_OK );
 }
 
 static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
@@ -647,25 +690,28 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     if ( smDS->NbNodes() < 1 )
       return true; // 1 segment
 
-    vector< double > mainEdgeParams;
-    if ( ! SMESH_Algo::GetNodeParamOnEdge( theMesh.GetMeshDS(), mainEdge, mainEdgeParams ))
+    map< double, const SMDS_MeshNode* > mainEdgeParamsOfNodes;
+    if ( ! SMESH_Algo::GetSortedNodesOnEdge( theMesh.GetMeshDS(), mainEdge, _quadraticMesh,
+                                             mainEdgeParamsOfNodes, SMDSAbs_Edge ))
       return error("Bad node parameters on the source edge of Propagation Of Distribution");
 
-    vector< double > segLen( mainEdgeParams.size() - 1 );
+    vector< double > segLen( mainEdgeParamsOfNodes.size() - 1 );
     double totalLen = 0;
     BRepAdaptor_Curve mainEdgeCurve( mainEdge );
-    for ( size_t i = 1; i < mainEdgeParams.size(); ++i )
+    map< double, const SMDS_MeshNode* >::iterator
+      u_n2 = mainEdgeParamsOfNodes.begin(), u_n1 = u_n2++;
+    for ( size_t i = 1; i < mainEdgeParamsOfNodes.size(); ++i, ++u_n1, ++u_n2 )
     {
       segLen[ i-1 ] = GCPnts_AbscissaPoint::Length( mainEdgeCurve,
-                                                    mainEdgeParams[i-1],
-                                                    mainEdgeParams[i]);
+                                                    u_n1->first,
+                                                    u_n2->first);
       totalLen += segLen[ i-1 ];
     }
     for ( size_t i = 0; i < segLen.size(); ++i )
       segLen[ i ] *= theLength / totalLen;
 
-    size_t iSeg = theReverse ? segLen.size()-1 : 0;
-    size_t dSeg = theReverse ? -1 : +1;
+    size_t  iSeg = theReverse ? segLen.size()-1 : 0;
+    size_t  dSeg = theReverse ? -1 : +1;
     double param = theFirstU;
     int nbParams = 0;
     for ( int i = 0, nb = segLen.size()-1; i < nb; ++i, iSeg += dSeg )
@@ -925,13 +971,13 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     {
       if ( Abs( param - Un ) < 0.2 * Abs( param - theParams.back() ))
       {
-        compensateError( a1, eltSize, U1, Un, theLength, theC3d, theParams );
+        compensateError( a1, Abs(eltSize), U1, Un, theLength, theC3d, theParams );
       }
       else if ( Abs( Un - theParams.back() ) <
-                0.2 * Abs( theParams.back() - *(--theParams.rbegin())))
+                0.2 * Abs( theParams.back() - *(++theParams.rbegin())))
       {
         theParams.pop_back();
-        compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
+        compensateError( a1, Abs(an), U1, Un, theLength, theC3d, theParams );
       }
     }
     if (theReverse) theParams.reverse(); // NPAL18025
@@ -1127,10 +1173,13 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
     }
     if ( !_mainEdge.IsNull() ) {
       // take into account reversing the edge the hypothesis is propagated from
+      // (_mainEdge.Orientation() marks mutual orientation of EDGEs in propagation chain)
       reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
-      int mainID = meshDS->ShapeToIndex(_mainEdge);
-      if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end())
-        reversed = !reversed;
+      if ( !_isPropagOfDistribution ) {
+        int mainID = meshDS->ShapeToIndex(_mainEdge);
+        if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end())
+          reversed = !reversed;
+      }
     }
     // take into account this edge reversing
     if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), shapeID) != _revEdgesIDs.end())
@@ -1336,12 +1385,11 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh &         aMesh,
   _usedHypList.clear();
   _mainEdge.Nullify();
 
-  SMESH_HypoFilter auxiliaryFilter, compatibleFilter;
-  auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() );
-  InitCompatibleHypoFilter( compatibleFilter, /*ignoreAux=*/true );
+  SMESH_HypoFilter auxiliaryFilter( SMESH_HypoFilter::IsAuxiliary() );
+  const SMESH_HypoFilter* compatibleFilter = GetCompatibleHypoFilter(/*ignoreAux=*/true );
 
   // get non-auxiliary assigned directly to aShape
-  int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false );
+  int nbHyp = aMesh.GetHypotheses( aShape, *compatibleFilter, _usedHypList, false );
 
   if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE)
   {
@@ -1352,7 +1400,7 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh &         aMesh,
     {
       // Propagation of 1D hypothesis from <aMainEdge> on this edge;
       // get non-auxiliary assigned to _mainEdge
-      nbHyp = aMesh.GetHypotheses( _mainEdge, compatibleFilter, _usedHypList, true );
+      nbHyp = aMesh.GetHypotheses( _mainEdge, *compatibleFilter, _usedHypList, true );
     }
   }