Salome HOME
limite hauteur interpolation stream
authorPaul RASCLE <paul.rascle@edf.fr>
Wed, 10 May 2017 06:34:17 +0000 (08:34 +0200)
committerPaul RASCLE <paul.rascle@edf.fr>
Wed, 10 May 2017 14:44:07 +0000 (16:44 +0200)
src/HYDROData/HYDROData_DTM.cxx
src/HYDROData/HYDROData_DTM.h
src/HYDRO_tests/test_HYDROData_DTM.cxx

index e8663739d2e8593aad855e9fe3b192481b3bc0d8..b31cdbcfe4ed812a783ce2ccc1a1336665094564 100644 (file)
@@ -61,8 +61,8 @@
 
 IMPLEMENT_STANDARD_RTTIEXT( HYDROData_DTM, HYDROData_Bathymetry )
 
-HYDROData_DTM::CurveUZ::CurveUZ( double theXCurv, const gp_Vec2d& theProfileDir, double theDeltaZ )
-  : myXcurv( theXCurv ), myProfileDir( theProfileDir ), myDeltaZ( theDeltaZ )
+HYDROData_DTM::CurveUZ::CurveUZ( double theXCurv, const gp_Vec2d& theProfileDir, double theDeltaZ, double theMaxZ )
+  : myXcurv( theXCurv ), myProfileDir( theProfileDir ), myDeltaZ( theDeltaZ ), myMaxZ (theMaxZ)
 {
 }
 
@@ -85,9 +85,14 @@ double HYDROData_DTM::CurveUZ::DeltaZ() const
   return myDeltaZ;
 }
 
+double HYDROData_DTM::CurveUZ::MaxZ() const
+{
+  return myMaxZ;
+}
+
 HYDROData_DTM::CurveUZ HYDROData_DTM::CurveUZ::operator + ( const CurveUZ& c ) const
 {
-  HYDROData_DTM::CurveUZ res( Xcurv() + c.Xcurv(), ProfileDir() + c.ProfileDir(), DeltaZ() + c.DeltaZ() );
+  HYDROData_DTM::CurveUZ res( Xcurv() + c.Xcurv(), ProfileDir() + c.ProfileDir(), DeltaZ() + c.DeltaZ(), MaxZ() + c.MaxZ() );
   size_t n = size(), n1 = c.size();
   if( n!=n1 )
   {
@@ -106,7 +111,7 @@ HYDROData_DTM::CurveUZ HYDROData_DTM::CurveUZ::operator + ( const CurveUZ& c ) c
 
 HYDROData_DTM::CurveUZ HYDROData_DTM::CurveUZ::operator * ( double d ) const
 {
-  HYDROData_DTM::CurveUZ res( Xcurv()*d, ProfileDir()*d, DeltaZ()*d );
+  HYDROData_DTM::CurveUZ res( Xcurv()*d, ProfileDir()*d, DeltaZ()*d, MaxZ()*d );
   size_t n = size();
   res.reserve( n );
   for( int i=0; i<n; i++ )
@@ -672,7 +677,7 @@ bool CalcMidWidth( const std::set<double>& intersections, double& theMid, double
 }
 
 void HYDROData_DTM::ProfileDiscretization( const Handle(HYDROData_Profile)& theProfile, 
-                                           double theXCurv, double theMinZ, double theMaxZ, double theDDZ,
+                                           double theXCurv, double theMinZ, double theMaxZ, double theTopZ, double theDDZ,
                                            CurveUZ& theMidPointCurve,
                                            CurveUZ& theWidthCurve,                                           
                                            int& intersection_nb,
@@ -704,9 +709,9 @@ void HYDROData_DTM::ProfileDiscretization( const Handle(HYDROData_Profile)& theP
   curves.push_back( aT2 );
   
   int psize = ( int )( ( theMaxZ-theMinZ ) / theDDZ + 1 );
-  theMidPointCurve = CurveUZ( theXCurv, aProfileDir, theMinZ );
+  theMidPointCurve = CurveUZ( theXCurv, aProfileDir, theMinZ, theTopZ);
   theMidPointCurve.reserve( psize );
-  theWidthCurve = CurveUZ( theXCurv, aProfileDir, theMinZ );
+  theWidthCurve = CurveUZ( theXCurv, aProfileDir, theMinZ, theTopZ );
   theWidthCurve.reserve( psize );
 
   n = curves.size();
@@ -780,7 +785,8 @@ void HYDROData_DTM::CurveTo3D( const Handle(Geom2d_BSplineCurve)& theHydraulicAx
   
   size_t n = theMidCurve.size();
   std::map<double, AltitudePoint> sorted_points;
-  for( size_t i=0; i<n; i++ )
+  bool isOnTop = false;
+  for( size_t i=0; i<n; i++ ) // build the two banks of the interpolated profile, from bottom to top
   {
     double param1 = theMidCurve[i].U - theWidthCurve[i].U / 2;
     double param2 = theMidCurve[i].U + theWidthCurve[i].U / 2;
@@ -788,12 +794,24 @@ void HYDROData_DTM::CurveTo3D( const Handle(Geom2d_BSplineCurve)& theHydraulicAx
     gp_Pnt2d p1 = point.Translated( param1 * profile_dir);
     gp_Pnt2d p2 = point.Translated( param2 * profile_dir);
 
-    double z = theMidCurve[i].Z + theMidCurve.DeltaZ();
-
-    AltitudePoint p3d_1( p1.X(), p1.Y(), z ), p3d_2( p2.X(), p2.Y(), z );
-
-    sorted_points[param1] = p3d_1;
-    sorted_points[param2] = p3d_2;
+    bool arrivedOnTop = false;
+    double z = 0;
+    if (theMidCurve[i].Z <= theMidCurve.MaxZ())
+      z = theMidCurve[i].Z + theMidCurve.DeltaZ();
+    else
+      {
+        z = theMidCurve.MaxZ() + theMidCurve.DeltaZ(); // limit z to linear interpolation between maxima on extremity profiles
+        arrivedOnTop = true; // do not keep points after this one
+      }
+    if (!isOnTop)
+      {
+        AltitudePoint p3d_1( p1.X(), p1.Y(), z ), p3d_2( p2.X(), p2.Y(), z );
+
+        sorted_points[param1] = p3d_1;
+        sorted_points[param2] = p3d_2;
+      }
+    //if (arrivedOnTop)
+    //  isOnTop =true; // do not keep points after this one (commented: leads to strange limits of 2D shape)
   }
 
   thePoints.reserve( sorted_points.size() );
@@ -845,11 +863,11 @@ std::vector<HYDROData_Bathymetry::AltitudePoints> HYDROData_DTM::Interpolate
   //double zmin = min( zminA, zminB );
   //double zmax = max( zmaxA, zmaxB );
 
-  CurveUZ midA(0, gp_Vec2d(), 0), midB(0, gp_Vec2d(), 0);
-  CurveUZ widA(0, gp_Vec2d(), 0), widB(0, gp_Vec2d(), 0);
+  CurveUZ midA(0, gp_Vec2d(), 0, 0), midB(0, gp_Vec2d(), 0, 0);
+  CurveUZ widA(0, gp_Vec2d(), 0, 0), widB(0, gp_Vec2d(), 0, 0);
 
-  ProfileDiscretization( theProfileA, theXCurvA, zminA, zminA+hmax, theDDZ, midA, widA, inter_nb_1 ); 
-  ProfileDiscretization( theProfileB, theXCurvB, zminB, zminB+hmax, theDDZ, midB, widB, inter_nb_2 );
+  ProfileDiscretization( theProfileA, theXCurvA, zminA, zminA+hmax, zmaxA-zminA, theDDZ, midA, widA, inter_nb_1 );
+  ProfileDiscretization( theProfileB, theXCurvB, zminB, zminB+hmax, zmaxB-zminB, theDDZ, midB, widB, inter_nb_2 );
 
   std::vector<CurveUZ> mid, wid;
   Interpolate( midA, midB, theNbSteps, mid, isAddSecond );
index 7f2de733cc173ed0acaf8aa92414bd23ab78905d..59d3cd6811e8a7f60c67620e63f6512661e8cc50 100644 (file)
@@ -90,12 +90,13 @@ public:
   class CurveUZ : public std::vector<PointUZ>
   {
   public:
-    CurveUZ( double theXcurv, const gp_Vec2d& theProfileDir, double theDeltaZ );
+    CurveUZ( double theXcurv, const gp_Vec2d& theProfileDir, double theDeltaZ, double theMaxZ );
     ~CurveUZ();
 
     double Xcurv() const;
     gp_Vec2d ProfileDir() const;
     double DeltaZ() const;
+    double MaxZ() const;
 
     CurveUZ operator + ( const CurveUZ& ) const;
     CurveUZ operator * ( double ) const;
@@ -104,6 +105,7 @@ public:
     double myXcurv;
     gp_Vec2d myProfileDir;
     double myDeltaZ;
+    double myMaxZ;
   };
 
 protected:
@@ -127,7 +129,7 @@ protected:
                              double& theZMin, double& theZMax );
 
   static void ProfileDiscretization( const Handle(HYDROData_Profile)& theProfile,
-                                     double theXCurv, double theMinZ, double theMaxZ, double theDDZ,
+                                     double theXCurv, double theMinZ, double theMaxZ, double theTopZ, double theDDZ,
                                      CurveUZ& theMidPointCurve,
                                      CurveUZ& theWidthCurve,
                                      int& intersection_nb,
index 74bf64ba87b192f93add72abc00e2dd9186b3765..d433872248c39cf96cbb268c618ba61b5e856ef6 100644 (file)
@@ -339,9 +339,9 @@ void test_HYDROData_DTM::test_profile_discretization_polyline()
   aProfile->SetLeftPoint( gp_XY( 10, 10 ) );
   aProfile->SetRightPoint( gp_XY( 20, 20 ) );
 
-  HYDROData_DTM::CurveUZ aMid( 0.0, gp_Vec2d(), 0 ), aWid( 0.0, gp_Vec2d(), 0 );
+  HYDROData_DTM::CurveUZ aMid( 0.0, gp_Vec2d(), 0, 0 ), aWid( 0.0, gp_Vec2d(), 0, 0 );
   int dummy = 0;
-  HYDROData_DTM::ProfileDiscretization( aProfile, 0.0, 0.0, 5.0, 0.5, aMid, aWid, dummy );
+  HYDROData_DTM::ProfileDiscretization( aProfile, 0.0, 0.0, 5.0, 5.0, 0.5, aMid, aWid, dummy );
   CPPUNIT_ASSERT_EQUAL( 11, (int)aMid.size() );
   CPPUNIT_ASSERT_DOUBLES_EQUAL(  0.0,   aMid[0].U, EPS );
   CPPUNIT_ASSERT_DOUBLES_EQUAL(  0.0,   aMid[0].Z, EPS );
@@ -377,9 +377,9 @@ Handle(HYDROData_Document) aDoc = HYDROData_Document::Document(1);
   aProfile->SetLeftPoint( gp_XY( 10, 10 ) );
   aProfile->SetRightPoint( gp_XY( 20, 20 ) );
 
-  HYDROData_DTM::CurveUZ aMid( 0.0, gp_Vec2d(), 0 ), aWid( 0.0, gp_Vec2d(), 0 );
+  HYDROData_DTM::CurveUZ aMid( 0.0, gp_Vec2d(), 0, 0 ), aWid( 0.0, gp_Vec2d(), 0, 0 );
   int dummy = 0 ;
-  HYDROData_DTM::ProfileDiscretization( aProfile, 0.0, 0.0, 5.0, 0.5, aMid, aWid, dummy );
+  HYDROData_DTM::ProfileDiscretization( aProfile, 0.0, 0.0, 5.0, 5.0, 0.5, aMid, aWid, dummy );
   CPPUNIT_ASSERT_EQUAL( 11, (int)aMid.size() );
   CPPUNIT_ASSERT_DOUBLES_EQUAL(  0.242, aMid[0].U, EPS );
   CPPUNIT_ASSERT_DOUBLES_EQUAL(  0.0,   aMid[0].Z, EPS );
@@ -432,7 +432,7 @@ void operator << ( std::ostream& s, const HYDROData_DTM::CurveUZ& c )
 
 void test_HYDROData_DTM::test_curves_interpolation()
 {
-  HYDROData_DTM::CurveUZ A(1.0, gp_Vec2d(), 0), B(2.0, gp_Vec2d(), 0);
+  HYDROData_DTM::CurveUZ A(1.0, gp_Vec2d(), 0, 0), B(2.0, gp_Vec2d(), 0, 0);
   A.push_back( HYDROData_DTM::PointUZ( 0, 0 ) );
   A.push_back( HYDROData_DTM::PointUZ( 1, 1 ) );
   A.push_back( HYDROData_DTM::PointUZ( 2, 2 ) );
@@ -499,10 +499,10 @@ void test_HYDROData_DTM::test_curve_to_3d()
 
   Handle(Geom2d_BSplineCurve) HA = HYDROData_DTM::CreateHydraulicAxis( profiles, distances );
   HYDROData_DTM::AltitudePoints points;
-  HYDROData_DTM::CurveUZ mid( 5.0, gp_Vec2d(-10,10), 0 );
+  HYDROData_DTM::CurveUZ mid( 5.0, gp_Vec2d(-10,10), 0, 0 );
   mid.push_back( HYDROData_DTM::PointUZ( 0, 5 ) );
   mid.push_back( HYDROData_DTM::PointUZ( 1, 6 ) );
-  HYDROData_DTM::CurveUZ wid( 5.0, gp_Vec2d(-10,10), 0 );
+  HYDROData_DTM::CurveUZ wid( 5.0, gp_Vec2d(-10,10), 0, 0 );
   wid.push_back( HYDROData_DTM::PointUZ( 2, 5 ) );
   wid.push_back( HYDROData_DTM::PointUZ( 6, 6 ) );
   HYDROData_DTM::CurveTo3D( HA, mid, wid, points );