Salome HOME
Merge from V5_1_main 14/05/2010
[modules/smesh.git] / src / StdMeshers / StdMeshers_Regular_1D.cxx
index 9f588499f80a34f915e29c492ff3a51995e4422f..391bd38c3c11df989aa6073ca8e7585582870acd 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//  Copyright (C) 2007-2010  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
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Regular_1D.cxx
 //           Moved here from SMESH_Regular_1D.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-
+//
 #include "StdMeshers_Regular_1D.hxx"
 #include "StdMeshers_Distribution.hxx"
 
@@ -63,6 +64,7 @@
 #include <TopoDS_Edge.hxx>
 
 #include <string>
+#include <limits>
 
 using namespace std;
 
@@ -73,22 +75,24 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
-       SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
+        SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
 {
-       MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
-       _name = "Regular_1D";
-       _shapeType = (1 << TopAbs_EDGE);
-
-       _compatibleHypothesis.push_back("LocalLength");
-       _compatibleHypothesis.push_back("MaxLength");
-       _compatibleHypothesis.push_back("NumberOfSegments");
-       _compatibleHypothesis.push_back("StartEndLength");
-       _compatibleHypothesis.push_back("Deflection1D");
-       _compatibleHypothesis.push_back("Arithmetic1D");
-       _compatibleHypothesis.push_back("AutomaticLength");
-
-       _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
-       _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
+        MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
+        _name = "Regular_1D";
+        _shapeType = (1 << TopAbs_EDGE);
+        _fpHyp = 0;
+
+        _compatibleHypothesis.push_back("LocalLength");
+        _compatibleHypothesis.push_back("MaxLength");
+        _compatibleHypothesis.push_back("NumberOfSegments");
+        _compatibleHypothesis.push_back("StartEndLength");
+        _compatibleHypothesis.push_back("Deflection1D");
+        _compatibleHypothesis.push_back("Arithmetic1D");
+        _compatibleHypothesis.push_back("FixedPoints1D");
+        _compatibleHypothesis.push_back("AutomaticLength");
+
+        _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
+        _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
 }
 
 //=============================================================================
@@ -218,6 +222,16 @@ bool StdMeshers_Regular_1D::CheckHypothesis
     aStatus = SMESH_Hypothesis::HYP_OK;
   }
 
+  else if (hypName == "FixedPoints1D") {
+    _fpHyp = dynamic_cast <const StdMeshers_FixedPoints1D*>(theHyp);
+    ASSERT(_fpHyp);
+    _hypType = FIXED_POINTS_1D;
+
+    _revEdgesIDs = _fpHyp->GetReversedEdges();
+
+    aStatus = SMESH_Hypothesis::HYP_OK;
+  }
+
   else if (hypName == "StartEndLength")
   {
     const StdMeshers_StartEndLength * hyp =
@@ -312,6 +326,8 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
       return false;
     prevU = U;
   }
+  if ( theReverse )
+    theParams.reverse();
   return true;
 }
 
@@ -745,7 +761,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     double an = _value[ END_LENGTH_IND ];
 
     double  q = ( an - a1 ) / ( 2 *theLength/( a1 + an ) - 1 );
-    int     n = int( 1 + ( an - a1 ) / q );
+    int n = int(fabs(q) > numeric_limits<double>::min() ? ( 1+( an-a1 )/q ) : ( 1+theLength/a1 ));
 
     double U1 = theReverse ? l : f;
     double Un = theReverse ? f : l;
@@ -773,6 +789,107 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     return true;
   }
 
+  case FIXED_POINTS_1D: {
+    const std::vector<double>& aPnts = _fpHyp->GetPoints();
+    const std::vector<int>& nbsegs = _fpHyp->GetNbSegments();
+    int i = 0;
+    TColStd_SequenceOfReal Params;
+    for(; i<aPnts.size(); i++) {
+      if( aPnts[i]<0.0001 || aPnts[i]>0.9999 ) continue;
+      int j=1;
+      bool IsExist = false;
+      for(; j<=Params.Length(); j++) {
+        if( fabs(aPnts[i]-Params.Value(j)) < 1e-4 ) {
+          IsExist = true;
+          break;
+        }
+        if( aPnts[i]<Params.Value(j) ) break;
+      }
+      if(!IsExist) Params.InsertBefore(j,aPnts[i]);
+    }
+    double par2, par1, lp;
+    par1 = f;
+    lp = l;
+    double sign = 1.0;
+    if(theReverse) {
+      par1 = l;
+      lp = f;
+      sign = -1.0;
+    }
+    double eltSize, segmentSize = 0.;
+    double currAbscissa = 0;
+    for(i=0; i<Params.Length(); i++) {
+      int nbseg = ( i > nbsegs.size()-1 ) ? nbsegs[0] : nbsegs[i];
+      segmentSize = Params.Value(i+1)*theLength - currAbscissa;
+      currAbscissa += segmentSize;
+      GCPnts_AbscissaPoint APnt(theC3d, sign*segmentSize, par1);
+      if( !APnt.IsDone() )
+        return error( "GCPnts_AbscissaPoint failed");
+      par2 = APnt.Parameter();
+      eltSize = segmentSize/nbseg;
+      GCPnts_UniformAbscissa Discret(theC3d, eltSize, par1, par2);
+      if(theReverse)
+        Discret.Initialize(theC3d, eltSize, par2, par1);
+      else
+        Discret.Initialize(theC3d, eltSize, par1, par2);
+      if ( !Discret.IsDone() )
+        return error( "GCPnts_UniformAbscissa failed");
+      int NbPoints = Discret.NbPoints();
+      list<double> tmpParams;
+      for(int i=2; i<NbPoints; i++) {
+        double param = Discret.Parameter(i);
+        tmpParams.push_back( param );
+      }
+      if (theReverse) {
+        compensateError( eltSize, eltSize, par2, par1, segmentSize, theC3d, tmpParams );
+        tmpParams.reverse();
+      }
+      else {
+        compensateError( eltSize, eltSize, par1, par2, segmentSize, theC3d, tmpParams );
+      }
+      list<double>::iterator itP = tmpParams.begin();
+      for(; itP != tmpParams.end(); itP++) {
+        theParams.push_back( *(itP) );
+      }
+      theParams.push_back( par2 );
+
+      par1 = par2;
+    }
+    // add for last
+    int nbseg = ( nbsegs.size() > Params.Length() ) ? nbsegs[Params.Length()] : nbsegs[0];
+    segmentSize = theLength - currAbscissa;
+    eltSize = segmentSize/nbseg;
+    GCPnts_UniformAbscissa Discret;
+    if(theReverse)
+      Discret.Initialize(theC3d, eltSize, par1, lp);
+    else
+      Discret.Initialize(theC3d, eltSize, lp, par1);
+    if ( !Discret.IsDone() )
+      return error( "GCPnts_UniformAbscissa failed");
+    int NbPoints = Discret.NbPoints();
+    list<double> tmpParams;
+    for(int i=2; i<NbPoints; i++) {
+      double param = Discret.Parameter(i);
+      tmpParams.push_back( param );
+    }
+    if (theReverse) {
+      compensateError( eltSize, eltSize, lp, par1, segmentSize, theC3d, tmpParams );
+      tmpParams.reverse();
+    }
+    else {
+      compensateError( eltSize, eltSize, par1, lp, segmentSize, theC3d, tmpParams );
+    }
+    list<double>::iterator itP = tmpParams.begin();
+    for(; itP != tmpParams.end(); itP++) {
+      theParams.push_back( *(itP) );
+    }
+
+    if (theReverse) {
+      theParams.reverse(); // NPAL18025
+    }
+    return true;
+  }
+
   case DEFLECTION: {
 
     GCPnts_UniformDeflection Discret(theC3d, _value[ DEFLECTION_IND ], f, l, true);
@@ -828,14 +945,18 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
   {
     list< double > params;
     bool reversed = false;
-    if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE )
+    if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE ) {
       reversed = ( EE.Orientation() == TopAbs_REVERSED );
-    if ( !_mainEdge.IsNull() )
+    }
+    if ( !_mainEdge.IsNull() ) {
       reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
+    }
     else if ( _revEdgesIDs.size() > 0 ) {
-      for ( int i = 0; i < _revEdgesIDs.size(); i++)
-       if ( _revEdgesIDs[i] == shapeID )
-         reversed = !reversed;
+      for ( int i = 0; i < _revEdgesIDs.size(); i++) {
+        if ( _revEdgesIDs[i] == shapeID ) {
+          reversed = !reversed;
+        }
+      }
     }
 
     BRepAdaptor_Curve C3d( E );
@@ -954,13 +1075,13 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
 //=============================================================================
 
 bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
-                                    const TopoDS_Shape & theShape,
-                                    MapShapeNbElems& aResMap)
+                                     const TopoDS_Shape & theShape,
+                                     MapShapeNbElems& aResMap)
 {
   if ( _hypType == NONE )
     return false;
 
-  SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+  //SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
 
   const TopoDS_Edge & EE = TopoDS::Edge(theShape);
   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
@@ -975,8 +1096,7 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
   ASSERT(!VFirst.IsNull());
   ASSERT(!VLast.IsNull());
 
-  std::vector<int> aVec(17);
-  for(int i=0; i<17; i++) aVec[i] = 0;
+  std::vector<int> aVec(SMDSEntity_Last,0);
 
   if (!Curve.IsNull()) {
     list< double > params;
@@ -993,12 +1113,12 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
     redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast );
 
     if(_quadraticMesh) {
-      aVec[0] = 2*params.size() + 1;
-      aVec[2] = params.size() + 1;
+      aVec[SMDSEntity_Node] = 2*params.size() + 1;
+      aVec[SMDSEntity_Quad_Edge] = params.size() + 1;
     }
     else {
-      aVec[0] = params.size();
-      aVec[1] = params.size() + 1;
+      aVec[SMDSEntity_Node] = params.size();
+      aVec[SMDSEntity_Edge] = params.size() + 1;
     }
     
   }
@@ -1006,12 +1126,12 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
     //MESSAGE("************* Degenerated edge! *****************");
     // Edge is a degenerated Edge : We put n = 5 points on the edge.
     if(_quadraticMesh) {
-      aVec[0] = 11;
-      aVec[2] = 6;
+      aVec[SMDSEntity_Node] = 11;
+      aVec[SMDSEntity_Quad_Edge] = 6;
     }
     else {
-      aVec[0] = 5;
-      aVec[1] = 6;
+      aVec[SMDSEntity_Node] = 5;
+      aVec[SMDSEntity_Edge] = 6;
     }
   }