]> SALOME platform Git repositories - modules/hydro.git/commitdiff
Salome HOME
refs #493: add data model methods implementation
authormzn <mzn@opencascade.com>
Mon, 30 Mar 2015 11:21:43 +0000 (14:21 +0300)
committermzn <mzn@opencascade.com>
Mon, 30 Mar 2015 11:21:43 +0000 (14:21 +0300)
src/HYDROData/HYDROData_IProfilesInterpolator.cxx
src/HYDROData/HYDROData_IProfilesInterpolator.h
src/HYDROData/HYDROData_LinearInterpolator.cxx
src/HYDROData/HYDROData_LinearInterpolator.h
src/HYDROData/HYDROData_Stream.cxx
src/HYDROData/HYDROData_Stream.h
src/HYDROGUI/HYDROGUI_ProfileInterpolateOp.cxx
src/HYDROGUI/HYDROGUI_ProfileInterpolateOp.h

index f0c8d42027730a4e6f2d50aef8897d3bc2ff2112..2af03fd7e29179a4c18451328fb8b3217c3e8556 100644 (file)
@@ -80,7 +80,7 @@ std::vector<double> HYDROData_IProfilesInterpolator::GetResultProfile( const int
 {
   std::vector<double> aResultProfile;
 
-  if ( theProfileIndex > 0 && theProfileIndex < (int) myResultProfiles.size() ) {
+  if ( theProfileIndex >= 0 && theProfileIndex < (int) myResultProfiles.size() ) {
     aResultProfile = myResultProfiles.at( theProfileIndex );
   }
 
@@ -89,14 +89,43 @@ std::vector<double> HYDROData_IProfilesInterpolator::GetResultProfile( const int
 
 void HYDROData_IProfilesInterpolator::Reset()
 {
+  // Reset input parameters
   myProfile1.clear();  
   myProfile2.clear();  
   myParameters.clear();
 
   SetResultProfilesNumber( DEFAULT_RESULT_PROFILES_NB );
   
+  // Reset result data
+  ClearResults();
+}
+
+std::vector<double> HYDROData_IProfilesInterpolator::GetFirstProfile() const
+{
+  return myProfile1;
+}
+
+std::vector<double> HYDROData_IProfilesInterpolator::GetSecondProfile() const
+{
+  return myProfile2;
+}
+
+void HYDROData_IProfilesInterpolator::ClearResults()
+{
+  // Clear result data
   myResultProfiles.clear();
 
+  // Reset errors
   SetErrorCode( OK );
   SetErrorMessage( "" );
+}
+
+int HYDROData_IProfilesInterpolator::GetNbProfilesToCompute() const
+{
+  return myResultProfilesNumber;
+}
+
+void HYDROData_IProfilesInterpolator::InsertResultProfile( const std::vector<double>& theProfile )
+{
+  myResultProfiles.push_back( theProfile );
 }
\ No newline at end of file
index a98c70fc8334c2d70a3d15afec1f2cb3e8e13f2c..c1a0949d2adafa47ba5f2b90cb4c8c8af8836a8f 100644 (file)
@@ -106,8 +106,12 @@ public:
   /**
    * Perform interpolation calculations.
    */
-  HYDRODATA_EXPORT virtual InterpolationError Calculate() = 0;
+  HYDRODATA_EXPORT virtual void Calculate() = 0;
 
+  /**
+   * Get number of calculated profiles ( could be less than the number of profiles to be computed set as a parameter ).
+   * @return the number of really calculated profiles
+   */
   HYDRODATA_EXPORT virtual int GetCalculatedProfilesNumber() const;
 
   /**
@@ -130,6 +134,35 @@ protected:
    */
   HYDRODATA_EXPORT virtual void SetErrorMessage( const std::string& theMessage );
 
+  /**
+   * Get the first profile.
+   * \return the first profile points
+   */
+  HYDRODATA_EXPORT std::vector<double> GetFirstProfile() const;
+
+  /**
+   * Get the second profile.
+   * \return the second profile points
+   */
+  HYDRODATA_EXPORT std::vector<double> GetSecondProfile() const;
+
+  /**
+   * Get number of profiles to compute.
+   * \return the current value of number of result profiles parameter
+   */
+  HYDRODATA_EXPORT virtual int GetNbProfilesToCompute() const;
+
+  /**
+   * Clear result data (including errors).
+   */
+  HYDRODATA_EXPORT void ClearResults();
+
+  /**
+   * Insert the calculated profile to the resuls.
+   * \param theProfile the profile to insert
+   */
+  HYDRODATA_EXPORT void InsertResultProfile( const std::vector<double>& theProfile );
+
 private:
   std::vector<double> myProfile1, myProfile2; ///< the two input profiles
   int myResultProfilesNumber; ///< the number of profiles to compute
index af2eb24c24f8fc290d1290189028f4e3c12f725d..fedb3f12b8b9066f03c68817876060a042fa9167 100644 (file)
@@ -38,7 +38,73 @@ std::string HYDROData_LinearInterpolator::GetDescription() const
   return aDescription;
 }
 
-InterpolationError HYDROData_LinearInterpolator::Calculate()
+void HYDROData_LinearInterpolator::Calculate()
 {
-  return OK;
+  // Reset result data
+  ClearResults();
+
+  // Check input data
+  std::vector<double> aProfile1 = GetFirstProfile();
+  std::vector<double> aProfile2 = GetSecondProfile();
+  int aNbProfilesToCompute = GetNbProfilesToCompute();
+
+  int aSize1 = aProfile1.size();
+  int aSize2 = aProfile2.size();
+
+  div_t aDiv1 = std::div( aSize1, 3 );
+  div_t aDiv2 = std::div( aSize2, 3 );
+  
+  if ( aNbProfilesToCompute < 1 ||
+       aSize1 < 2 || aDiv1.rem != 0 ||
+       aSize2 < 2 || aDiv2.rem != 0 ) {
+    SetErrorCode( InvalidParametersError );
+    return;
+  }
+
+  bool isSame = false;
+  if ( aSize1 < aSize2 ) {
+    isSame = std::equal( aProfile1.begin(), aProfile1.end(), aProfile2.begin() );
+  } else {
+    isSame = std::equal( aProfile2.begin(), aProfile2.end(), aProfile1.begin() );
+  }
+
+  if ( isSame ) {
+    SetErrorCode( InvalidParametersError );
+    return;
+  }
+
+  // Linear interpolation
+  InterpolationError aStatus = OK;
+
+  // the first profile should have the equal or less number of points than the second profile
+  int aNbPoints1 = aDiv1.quot;
+  int aNbPoints2 = aDiv2.quot;
+  if ( aNbPoints1 > aNbPoints2 ) {
+    aProfile1.swap( aProfile2 );
+    std::swap( aNbPoints1, aNbPoints2 );
+  }
+
+  for ( int k = 0; k <= aNbProfilesToCompute - 1; k++ ) {
+    std::vector<double> aResultProfile; ///< the k-th computed profile
+
+    double aRelParam = (double)( k + 1 ) / ( aNbProfilesToCompute + 1 );
+    for ( int i = 0; i <= aNbPoints1 - 1; i++ ) {
+      double aRel = ( aNbPoints2 - 1 ) / ( aNbPoints1 - 1 );
+      int aPointIndex = (int) std::floor( aRel * i ); ///< point index in the second profile
+      int anXindex1 = i * 3;
+      int anXindex2 = aPointIndex * 3;
+
+      double anXi = ( aProfile1[anXindex1] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2] * aRelParam );
+      double anYi = ( aProfile1[anXindex1 + 1] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2 + 1] * aRelParam );
+      double aZi = ( aProfile1[anXindex1 + 2] * ( 1 - aRelParam ) ) + ( aProfile2[anXindex2 + 2] * aRelParam );
+
+      aResultProfile.push_back( anXi );
+      aResultProfile.push_back( anYi );
+      aResultProfile.push_back( aZi );
+    }
+   
+    InsertResultProfile( aResultProfile );
+  }
+
+  SetErrorCode( aStatus );
 }
\ No newline at end of file
index df1bacb56d370e3a5d42ed5a002faecd007de6ea..4cd4e8e712a5902780fb7aa06143cc71791f9aa7 100644 (file)
@@ -53,7 +53,7 @@ public:
   /**
    *
    */
-  HYDRODATA_EXPORT virtual InterpolationError Calculate();
+  HYDRODATA_EXPORT virtual void Calculate();
 };
 
 #endif
index bf517b24aaff52ad5f92fe495056e6122d597043..6610c1fc0b8d9cc32853b18cc449877751d0623e 100644 (file)
@@ -29,6 +29,7 @@
 #include "HYDROData_ShapesGroup.h"
 #include "HYDROData_ShapesTool.h"
 #include "HYDROData_IAltitudeObject.h"
+#include "HYDROData_IProfilesInterpolator.h"
 #include "HYDROData_Tool.h"
 
 #include <TDataStd_RealArray.hxx>
@@ -1122,8 +1123,58 @@ Handle(HYDROData_Polyline3D) HYDROData_Stream::GetBottomPolyline() const
            GetReferenceObject( DataTag_BottomPolyline ) );
 }
 
-bool HYDROData_Stream::Interpolate( const HYDROData_IProfilesInterpolator* theInterpolator )
+bool HYDROData_Stream::Interpolate( HYDROData_IProfilesInterpolator* theInterpolator )
 {
-  ///< \todo this is just a stub
-  return true;
+  // Get the document
+  Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+  if ( aDocument.IsNull() ) {
+    return false;
+  }
+  
+  if ( theInterpolator->GetCalculatedProfilesNumber() < 1 ) {
+    theInterpolator->Calculate();
+  }
+
+  if ( theInterpolator->GetErrorCode() != OK ) {
+    return false;
+  }
+
+  bool isOK = true;
+
+  for ( int aProfileInd = 0; aProfileInd < theInterpolator->GetCalculatedProfilesNumber(); aProfileInd++ ) {
+    // Get calculated point coordinates
+    std::vector<double> aResultCoords = theInterpolator->GetResultProfile( aProfileInd );
+    div_t aDiv = std::div( aResultCoords.size(), 3 );
+    if ( aDiv.rem != 0 ) {
+      isOK = false;
+      continue;
+    }
+    
+    // Create profile object
+    Handle(HYDROData_Profile) aProfile = 
+      Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
+    QString aBaseName = GetName() + "_interp_profile";
+    QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName );
+    aProfile->SetName( aName );
+
+    // Fill the profile with points
+    HYDROData_Profile::ProfilePoints aProfilePoints;
+
+    int aPointsNb = aDiv.quot;
+    for ( int aPointInd = 0; aPointInd <= aPointsNb - 1; aPointInd++ ) {
+      int anXindex = aPointInd * 3;
+      double anX = aResultCoords[ anXindex ];
+      double anY = aResultCoords[ anXindex + 1 ];
+      double aZ  = aResultCoords[ anXindex + 2 ];
+
+      aProfilePoints.Append( gp_XYZ( anX, anY, aZ ) );
+    }
+
+    aProfile->SetProfilePoints( aProfilePoints );
+
+    // Add profile to the stream
+    isOK = AddProfile( aProfile ) && isOK;
+  }
+
+  return isOK;
 }
\ No newline at end of file
index 800438fe5962d63ef85dd2625ad6a6b0f7aba353..b80d588a24c8ff41d0eefbf69cdd0045aaaa607e 100644 (file)
@@ -250,7 +250,7 @@ public:
    * \param theInterpolator the interpolator
    * \return true in case of success
    */
-  HYDRODATA_EXPORT virtual bool Interpolate( const HYDROData_IProfilesInterpolator* theInterpolator );
+  HYDRODATA_EXPORT virtual bool Interpolate( HYDROData_IProfilesInterpolator* theInterpolator );
   
 protected:
 
index dab1a59e4f123294089f5b96f0098d605960e4bc..362ceb6ea291c8e5a1775b3542c1b5318174dc34 100644 (file)
@@ -136,7 +136,7 @@ bool HYDROGUI_ProfileInterpolateOp::processApply( int& theUpdateFlags, QString&
         if ( !aRiver.IsNull() )
         {
             startDocOperation();
-            //aRiver->Interpolate( anIterp );
+            aRiver->Interpolate( anIterp );
             if ( anIterp->GetErrorCode() == OK )
                 commitDocOperation();
             else
@@ -176,9 +176,10 @@ void HYDROGUI_ProfileInterpolateOp::updatePreview()
     if ( anIterp )
     {
         updateInterpolator( anIterp );
-        if ( anIterp->Calculate() == OK )
+        anIterp->Calculate();
+        if ( anIterp->GetErrorCode() == OK )
         {
-            TopoDS_Shape aShape = previewShape( anIterp, aDlg->profileNumber() );
+            TopoDS_Shape aShape = previewShape( anIterp );
             if ( !aShape.IsNull() )
             {
                 myPreview = new AIS_Shape( aShape );
@@ -284,18 +285,18 @@ HYDROData_IProfilesInterpolator* HYDROGUI_ProfileInterpolateOp::interpolator( co
     return aRes;
 }
 
-TopoDS_Shape HYDROGUI_ProfileInterpolateOp::previewShape( HYDROData_IProfilesInterpolator* theInterp, int theNumber ) const
+TopoDS_Shape HYDROGUI_ProfileInterpolateOp::previewShape( HYDROData_IProfilesInterpolator* theInterp ) const
 {
     TopoDS_Compound aPreviewShape;
     if ( theInterp )
     {
         BRep_Builder aBuilder;
         aBuilder.MakeCompound( aPreviewShape );
-        for ( int i = 0; i < theNumber; i++ )
+        for ( int i = 0; i < theInterp->GetCalculatedProfilesNumber(); i++ )
         {
             NCollection_Sequence<gp_XYZ> pointSeq;
             std::vector<double> aPoints = theInterp->GetResultProfile( i );
-            for ( int i = 0; i < aPoints.size(); i += 3 )
+            for ( int i = 0; i < (int) aPoints.size(); i += 3 )
                 pointSeq.Append( gp_XYZ( aPoints[i], aPoints[i+1], aPoints[i+2] ) );
             TopoDS_Shape aWire = HYDROData_PolylineXY::BuildWire( HYDROData_IPolyline::SECTION_SPLINE, false, pointSeq );
             if ( !aWire.IsNull() )
index dabd86ec18d52008c3ff0edb377038e8835734c0..e593acf51f9e037122a4defaa0040fc3d8a9ed49 100644 (file)
@@ -62,7 +62,7 @@ protected:
   ParamsList                 parameters( const QString& ) const;
   QString                    parameters( const ParamsList& ) const;
 
-  TopoDS_Shape               previewShape( HYDROData_IProfilesInterpolator*, int ) const;
+  TopoDS_Shape               previewShape( HYDROData_IProfilesInterpolator* ) const;
 
 private slots:
   void                       updatePreview();