]> SALOME platform Git repositories - modules/hydro.git/commitdiff
Salome HOME
First implementation of Profiles.
authoradv <adv@opencascade.com>
Thu, 7 Nov 2013 17:07:21 +0000 (17:07 +0000)
committeradv <adv@opencascade.com>
Thu, 7 Nov 2013 17:07:21 +0000 (17:07 +0000)
src/HYDROData/CMakeLists.txt
src/HYDROData/HYDROData_IPolyline.cxx [new file with mode: 0755]
src/HYDROData/HYDROData_IPolyline.h [new file with mode: 0644]
src/HYDROData/HYDROData_Iterator.cxx
src/HYDROData/HYDROData_Iterator.h
src/HYDROData/HYDROData_Profile.cxx [new file with mode: 0755]
src/HYDROData/HYDROData_Profile.h [new file with mode: 0644]
src/HYDROData/HYDROData_ProfileUZ.cxx [new file with mode: 0755]
src/HYDROData/HYDROData_ProfileUZ.h [new file with mode: 0644]
src/HYDROData/test_HYDROData_Profile.cxx [new file with mode: 0755]
src/HYDROData/test_HYDROData_Profile.h [new file with mode: 0755]

index 88b1f415f60186b700e53b668129bdc59958bf2d..30d7e9869229573dfdb2c667a9a4dc21e89b24fa 100644 (file)
@@ -16,6 +16,7 @@ set(PROJECT_HEADERS
     HYDROData_IAltitudeObject.h
     HYDROData_Image.h
     HYDROData_ImmersibleZone.h
+    HYDROData_IPolyline.h
     HYDROData_Iterator.h
     HYDROData_Lambert93.h
     HYDROData_NaturalObject.h
@@ -23,6 +24,8 @@ set(PROJECT_HEADERS
     HYDROData_Obstacle.h
     HYDROData_OperationsFactory.h
     HYDROData_Polyline.h
+    HYDROData_Profile.h
+    HYDROData_ProfileUZ.h
     HYDROData_Region.h
     HYDROData_River.h
     HYDROData_SplitToZonesTool.h
@@ -47,6 +50,7 @@ set(PROJECT_SOURCES
     HYDROData_IAltitudeObject.cxx
     HYDROData_Image.cxx
     HYDROData_ImmersibleZone.cxx
+    HYDROData_IPolyline.cxx
     HYDROData_Iterator.cxx
     HYDROData_Lambert93.cxx
     HYDROData_NaturalObject.cxx
@@ -54,6 +58,8 @@ set(PROJECT_SOURCES
     HYDROData_Obstacle.cxx
     HYDROData_OperationsFactory.cxx
     HYDROData_Polyline.cxx
+    HYDROData_Profile.cxx
+    HYDROData_ProfileUZ.cxx
     HYDROData_Region.cxx
     HYDROData_River.cxx
     HYDROData_SplitToZonesTool.cxx
@@ -95,6 +101,7 @@ if(CPPUNIT_IS_OK)
     test_HYDROData_Iterator.h
     test_HYDROData_OperationsFactory.h
     test_HYDROData_Polyline.h
+    test_HYDROData_Profile.h
   )
 
   set(TEST_SOURCES 
@@ -108,6 +115,7 @@ if(CPPUNIT_IS_OK)
     test_HYDROData_Iterator.cxx
     test_HYDROData_OperationsFactory.cxx
     test_HYDROData_Polyline.cxx
+    test_HYDROData_Profile.cxx
   )
   
   set(TEST_EXE test_HYDROData)
diff --git a/src/HYDROData/HYDROData_IPolyline.cxx b/src/HYDROData/HYDROData_IPolyline.cxx
new file mode 100755 (executable)
index 0000000..20fe209
--- /dev/null
@@ -0,0 +1,65 @@
+
+#include "HYDROData_IPolyline.h"
+
+#include <gp_XY.hxx>
+
+#include <TDataStd_RealList.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(HYDROData_IPolyline, HYDROData_Entity)
+IMPLEMENT_STANDARD_RTTIEXT(HYDROData_IPolyline, HYDROData_Entity)
+
+HYDROData_IPolyline::HYDROData_IPolyline()
+: HYDROData_Entity()
+{
+}
+
+HYDROData_IPolyline::~HYDROData_IPolyline()
+{
+}
+
+int HYDROData_IPolyline::NbPoints( const int theSectionIndex ) const
+{
+  return GetPoints( theSectionIndex ).Length();
+}
+
+void HYDROData_IPolyline::getPointsLists( const int                  theSectionIndex,
+                                          Handle(TDataStd_RealList)& theListX,
+                                          Handle(TDataStd_RealList)& theListY,
+                                          const bool                 theIsCreate ) const
+{
+  theListX.Nullify();
+  theListY.Nullify();
+
+  TDF_Label aLabel = myLab.FindChild( DataTag_Points, theIsCreate );
+  if ( aLabel.IsNull() )
+    return;
+
+  TDF_Label aSectLabel = aLabel.FindChild( theSectionIndex, theIsCreate );
+  if ( aSectLabel.IsNull() )
+    return;
+
+  TDF_Label aLabelX = aSectLabel.FindChild( 0, theIsCreate );
+  if ( !aLabelX.IsNull() )
+  {
+    if ( !aLabelX.FindAttribute( TDataStd_RealList::GetID(), theListX ) && theIsCreate )
+      theListX = TDataStd_RealList::Set( aLabelX );
+  }
+
+  TDF_Label aLabelY = aSectLabel.FindChild( 1, theIsCreate );
+  if ( !aLabelY.IsNull() )
+  {
+    if ( !aLabelY.FindAttribute( TDataStd_RealList::GetID(), theListY ) && theIsCreate )
+      theListY = TDataStd_RealList::Set( aLabelY );
+  }
+}
+
+void HYDROData_IPolyline::removePointsLists( const int theSectionIndex ) const
+{
+  TDF_Label aLabel = myLab.FindChild( DataTag_Points, false );
+  if ( aLabel.IsNull() )
+    return;
+
+  TDF_Label aSectLabel = aLabel.FindChild( theSectionIndex, false );
+  if ( !aSectLabel.IsNull() )
+    aSectLabel.ForgetAllAttributes();
+}
diff --git a/src/HYDROData/HYDROData_IPolyline.h b/src/HYDROData/HYDROData_IPolyline.h
new file mode 100644 (file)
index 0000000..9155f69
--- /dev/null
@@ -0,0 +1,138 @@
+
+#ifndef HYDROData_IPolyline_HeaderFile
+#define HYDROData_IPolyline_HeaderFile
+
+#include "HYDROData_Entity.h"
+
+
+DEFINE_STANDARD_HANDLE(HYDROData_IPolyline, HYDROData_Entity)
+
+class gp_XY;
+class TopoDS_Wire;
+class Handle(TDataStd_RealList);
+
+/**\class HYDROData_IPolyline
+ * \brief Base class that stores/retreives information about the 2D points.
+ */
+class HYDROData_IPolyline : public HYDROData_Entity
+{
+public:
+
+  typedef gp_XY                       Point;
+  typedef NCollection_Sequence<Point> PointsList;
+
+protected:
+  /**
+   * Enumeration of tags corresponding to the persistent object parameters.
+   */
+  enum DataTag
+  {
+    DataTag_First = HYDROData_Entity::DataTag_First + 100, ///< first tag, to reserve
+    DataTag_Points,
+  };
+
+public:
+  DEFINE_STANDARD_RTTI(HYDROData_IPolyline);
+
+  /**
+   * Returns the 3D presentation of all points.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Wire GetWire() const = 0;
+
+
+  /**
+   * Returns number of sections.
+   */
+  HYDRODATA_EXPORT virtual int NbSections() const = 0;
+
+  /**
+   * Adds new one section.
+   * \param theIsClosed flag indicates type of polyline
+   */
+  HYDRODATA_EXPORT virtual void AddSection( const bool theIsClosed ) = 0;
+
+  /**
+   * Returns true if section with given index is closed.
+   * \param theSectionIndex index of section
+   */
+  HYDRODATA_EXPORT virtual bool IsClosedSection( const int theSectionIndex ) const = 0;
+
+  /**
+   * Removes section with given index.
+   * \param theSectionIndex index of section
+   */
+  HYDRODATA_EXPORT virtual void RemoveSection( const int theSectionIndex ) = 0;
+
+  /**
+   * Removes all sections.
+   */
+  HYDRODATA_EXPORT virtual void RemoveSections() = 0;
+
+
+  /**
+   * Return number of profile points.
+   * \return number of points
+   */
+  HYDRODATA_EXPORT int NbPoints( const int theSectionIndex = -1 ) const;
+
+  /**
+   * Adds new point for section with index "theSectionIndex".
+   * \param theSectionIndex index of section
+   * \param thePoint point to add
+   * \param theBeforeIndex if not equal -1 then insert point before this index
+   */
+  HYDRODATA_EXPORT virtual void AddPoint( const int    theSectionIndex,
+                                          const Point& thePoint,
+                                          const int    theBeforeIndex = -1 ) = 0;
+
+  /**
+   * Replaces point for section with index "theSectionIndex".
+   * \param theSectionIndex index of section
+   * \param thePointIndex index of point to replace
+   * \param thePoint new point
+   */
+  HYDRODATA_EXPORT virtual void SetPoint( const int    theSectionIndex,
+                                          const int    thePointIndex,
+                                          const Point& thePoint ) = 0;
+
+  /**
+   * Removes point from section with index "theSectionIndex".
+   * \param theSectionIndex index of section
+   * \param thePointIndex index of point
+   */
+  HYDRODATA_EXPORT virtual void RemovePoint( const int theSectionIndex,
+                                             const int thePointIndex ) = 0;
+
+
+  /**
+   * Returns list of points.
+   * \param theSectionIndex if not equal -1 then list of points returned
+   *                        only for section with this index
+   * \return list of points
+   */
+  HYDRODATA_EXPORT virtual PointsList GetPoints( const int theSectionIndex = -1 ) const = 0;
+
+protected:
+
+  void getPointsLists( const int                  theSectionIndex,
+                       Handle(TDataStd_RealList)& theListX,
+                       Handle(TDataStd_RealList)& theListY,
+                       const bool                 theIsCreate = true ) const;
+
+  void removePointsLists( const int theSectionIndex ) const;
+
+protected:
+
+  /**
+   * Creates new object in the internal data structure. Use higher level objects 
+   * to create objects with real content.
+   */
+  HYDROData_IPolyline();
+
+  /**
+   * Destructs properties of the object and object itself, removes it from the document.
+   */
+  ~HYDROData_IPolyline();
+};
+
+#endif
index a096556793101a00a937b4bdb6cea2ea8c3f8f38..42585bfda1ae0f0c7af6a0a8e8ce7b0f7ee68d81 100644 (file)
@@ -11,6 +11,8 @@
 #include "HYDROData_ImmersibleZone.h"
 #include "HYDROData_Obstacle.h"
 #include "HYDROData_Polyline.h"
+#include "HYDROData_Profile.h"
+#include "HYDROData_ProfileUZ.h"
 #include "HYDROData_VisualState.h"
 #include "HYDROData_Region.h"
 #include "HYDROData_River.h"
@@ -133,6 +135,12 @@ Handle(HYDROData_Entity) HYDROData_Iterator::Object( const TDF_Label& theLabel )
     case KIND_DIGUE:
       aResult = new HYDROData_Digue();
       break;
+    case KIND_PROFILE:
+      aResult = new HYDROData_Profile();
+      break;
+    case KIND_PROFILEUZ:
+      aResult = new HYDROData_ProfileUZ();
+      break;
     case KIND_CALCULATION:
       aResult = new HYDROData_CalculationCase();
       break;
index 409787fc600db769b7da61cbbc4a01f28c9b306c..824579792fc560282ada87287ca4282a9a3e7da0 100644 (file)
@@ -49,6 +49,11 @@ public:
   static Handle(HYDROData_Entity) CreateObject( TDF_Label&        theNewLabel, 
                                                 const ObjectKind& theObjectKind );
 
+  /**
+   * Returns object associated to the given label.
+   */
+  static Handle(HYDROData_Entity) Object( const TDF_Label& theLabel );
+
 protected:
 
   friend class HYDROData_Document;
@@ -64,11 +69,6 @@ protected:
     const Handle(HYDROData_Document)& theDoc,
     const ObjectKind&                 theObjectKind );
 
-  /**
-   * Returns object associated to the given label.
-   */
-  static Handle(HYDROData_Entity) Object( const TDF_Label& theLabel );
-
   TDF_ChildIDIterator myIter; ///< iterator by the objects in the document
 };
 
diff --git a/src/HYDROData/HYDROData_Profile.cxx b/src/HYDROData/HYDROData_Profile.cxx
new file mode 100755 (executable)
index 0000000..9832cad
--- /dev/null
@@ -0,0 +1,484 @@
+
+#include "HYDROData_Profile.h"
+
+#include "HYDROData_Document.h"
+#include "HYDROData_Iterator.h"
+#include "HYDROData_Tool.h"
+
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+
+#include <gp_XY.hxx>
+#include <gp_XYZ.hxx>
+#include <gp_Pnt2d.hxx>
+
+#include <TDataStd_AsciiString.hxx>
+#include <TDataStd_RealArray.hxx>
+
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Wire.hxx>
+
+#include <OSD_File.hxx>
+#include <OSD_Protection.hxx>
+
+#include <QStringList>
+
+#define PYTHON_PROFILE_ID "KIND_PROFILE"
+
+IMPLEMENT_STANDARD_HANDLE(HYDROData_Profile, HYDROData_Object)
+IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Profile, HYDROData_Object)
+
+HYDROData_Profile::HYDROData_Profile()
+: HYDROData_Object()
+{
+}
+
+HYDROData_Profile::~HYDROData_Profile()
+{
+}
+
+TopoDS_Shape HYDROData_Profile::GetTopShape() const
+{
+  TopoDS_Wire aWire;
+
+  gp_XY aFirstPoint, aLastPoint;
+  if ( !GetFirstPoint( aFirstPoint ) || !GetLastPoint( aLastPoint ) )
+    return aWire;
+
+  gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
+  gp_Pnt aPnt2( aLastPoint.X(),  aLastPoint.Y(),  0 );
+
+  BRepBuilderAPI_MakeEdge aMakeEdge( aPnt1, aPnt2 );
+  TopoDS_Edge anEdge = aMakeEdge;
+
+  BRepBuilderAPI_MakeWire aMakeWire( anEdge );
+  aWire = aMakeWire;
+
+  return aWire;
+}
+
+TopoDS_Shape HYDROData_Profile::GetShape3D() const
+{
+  return getShape3D();
+}
+
+void HYDROData_Profile::UpdateShape3D()
+{
+  BRepBuilderAPI_MakeWire aMakeWire;
+
+  ProfilePoints aProfilePoints = GetProfilePoints();
+  for ( int i = 1, n = aProfilePoints.Length(); i < n ; ++i )
+  {
+    ProfilePoint aFirstPoint = aProfilePoints.Value( i );
+    ProfilePoint aSecPoint = aProfilePoints.Value( i + 1 );
+
+    gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), aFirstPoint.Z() );
+    gp_Pnt aPnt2( aSecPoint.X(),   aSecPoint.Y(),   aSecPoint.Z()   );
+
+    BRepBuilderAPI_MakeEdge aMakeEdge( aPnt1, aPnt2 );
+    TopoDS_Edge anEdge = aMakeEdge;
+
+    aMakeWire.Add( anEdge );
+  }
+
+  TopoDS_Wire aWire;
+  if ( aMakeWire.IsDone() )
+    aWire = aMakeWire;
+
+  SetShape3D( aWire );
+}
+
+/**
+ * Dump object to Python script representation.
+ */
+QStringList HYDROData_Profile::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
+{
+  QStringList aResList;
+
+  Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
+  if ( aDocument.IsNull() )
+    return aResList;
+                             
+  QString aDocName = aDocument->GetDocPyName();
+  QString aProfileName = GetName();
+
+  aResList << QString( "%1 = %2.CreateObject( %3 );" )
+              .arg( aProfileName ).arg( aDocName ).arg( PYTHON_PROFILE_ID );
+  aResList << QString( "%1.SetName( \"%1\" );" ).arg( aProfileName );
+
+  return aResList;
+}
+
+bool HYDROData_Profile::IsValid() const
+{
+  gp_XY aFirstPoint, aLastPoint;
+  if ( !GetFirstPoint( aFirstPoint ) || !GetLastPoint( aLastPoint ) )
+    return false;
+
+  int aNbPoints = NbPoints();
+  return aNbPoints > 1;
+}
+
+void HYDROData_Profile::SetFirstPoint( const gp_XY& thePoint )
+{
+  TDF_Label aLabel = myLab.FindChild( DataTag_FirstPoint );
+
+  Handle(TDataStd_RealArray) anArray;
+  if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
+    anArray = TDataStd_RealArray::Set( aLabel, 0, 1 );
+
+  anArray->SetValue( 0, thePoint.X() );
+  anArray->SetValue( 1, thePoint.Y() );
+}
+
+bool HYDROData_Profile::GetFirstPoint( gp_XY& thePoint ) const
+{
+  TDF_Label aLabel = myLab.FindChild( DataTag_FirstPoint, false );
+  if ( aLabel.IsNull() )
+    return false;
+
+  Handle(TDataStd_RealArray) anArray;
+  if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
+    return false;
+
+  thePoint.SetX( anArray->Value( 0 ) );
+  thePoint.SetY( anArray->Value( 1 ) );
+
+  return true;
+}
+
+void HYDROData_Profile::SetLastPoint( const gp_XY& thePoint )
+{
+  TDF_Label aLabel = myLab.FindChild( DataTag_LastPoint );
+
+  Handle(TDataStd_RealArray) anArray;
+  if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
+    anArray = TDataStd_RealArray::Set( aLabel, 0, 1 );
+
+  anArray->SetValue( 0, thePoint.X() );
+  anArray->SetValue( 1, thePoint.Y() );
+}
+
+bool HYDROData_Profile::GetLastPoint( gp_XY& thePoint ) const
+{
+  TDF_Label aLabel = myLab.FindChild( DataTag_LastPoint, false );
+  if ( aLabel.IsNull() )
+    return false;
+
+  Handle(TDataStd_RealArray) anArray;
+  if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
+    return false;
+
+  thePoint.SetX( anArray->Value( 0 ) );
+  thePoint.SetY( anArray->Value( 1 ) );
+
+  return true;
+}
+
+Handle(HYDROData_ProfileUZ) HYDROData_Profile::GetProfileUZ( const bool theIsCreate ) const
+{
+  Handle(HYDROData_ProfileUZ) aProfileUZ;
+
+  TDF_Label aLabel = myLab.FindChild( DataTag_ChildProfileUZ, theIsCreate );
+  if ( aLabel.IsNull() )
+    return aProfileUZ;
+
+  aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast( HYDROData_Iterator::Object( aLabel ) );
+  if ( aProfileUZ.IsNull() && theIsCreate )
+  {
+    aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast(
+      HYDROData_Iterator::CreateObject( aLabel, KIND_PROFILEUZ ) );
+  }
+
+  return aProfileUZ;
+}
+
+int HYDROData_Profile::NbPoints() const
+{
+  Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
+  return aProfileUZ.IsNull() ? 0 : aProfileUZ->NbPoints();
+}
+
+void HYDROData_Profile::RemovePoints()
+{
+  Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
+  if ( !aProfileUZ.IsNull() )
+    aProfileUZ->RemoveSections();
+}
+
+void HYDROData_Profile::SetParametricPoints( const HYDROData_ProfileUZ::PointsList& thePoints )
+{
+  RemovePoints();
+
+  Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
+  for ( int i = 1, n = thePoints.Length(); i <= n ; ++i )
+  {
+    const HYDROData_ProfileUZ::Point& aPoint = thePoints.Value( i );
+    aProfileUZ->AddPoint( 0, aPoint );
+  }
+}
+
+HYDROData_ProfileUZ::PointsList HYDROData_Profile::GetParametricPoints() const
+{
+  Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
+  return aProfileUZ.IsNull() ? HYDROData_ProfileUZ::PointsList() : aProfileUZ->GetPoints();
+}
+
+void HYDROData_Profile::SetProfilePoints( const ProfilePoints& thePoints )
+{
+  RemovePoints();
+  if ( thePoints.Length() < 2 )
+    return;
+
+  gp_XY aFirstPoint, aLastPoint;
+
+  Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
+  for ( int i = 1, n = thePoints.Length(); i <= n ; ++i )
+  {
+    const ProfilePoint& aPoint = thePoints.Value( i );
+    gp_XY aPointXY( aPoint.X(), aPoint.Y() );
+
+    if ( i == 1 )
+      aFirstPoint = aPointXY;
+    else if ( i == n )
+      aLastPoint = aPointXY;
+
+    double aDistance = gp_Pnt2d( aFirstPoint ).Distance( aPointXY );
+    
+    HYDROData_ProfileUZ::Point aParPoint( aDistance, aPoint.Z() );
+    aProfileUZ->AddPoint( 0, aParPoint );
+  }
+
+  SetFirstPoint( aFirstPoint );
+  SetLastPoint( aLastPoint );
+}
+
+HYDROData_Profile::ProfilePoints HYDROData_Profile::GetProfilePoints() const
+{
+  ProfilePoints aResPoints;
+
+  gp_XY aFirstPoint, aLastPoint;
+  if ( !GetFirstPoint( aFirstPoint ) || !GetLastPoint( aLastPoint ) )
+    return aResPoints;
+
+  HYDROData_ProfileUZ::PointsList aParametricPoints = GetParametricPoints();
+  if ( aParametricPoints.Length() < 2 )
+    return aResPoints;
+
+  const HYDROData_ProfileUZ::Point& aFirstParPoint = aParametricPoints.First();
+  const HYDROData_ProfileUZ::Point& aLastParPoint = aParametricPoints.Last();
+
+  double aGeoDistance = gp_Pnt2d( aFirstPoint ).Distance( aLastPoint );
+  double aParCommonDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aLastParPoint.X(), 0 ) );
+
+  // Add first point as is
+  aResPoints.Append( ProfilePoint( aFirstPoint.X(), aFirstPoint.Y(), aFirstParPoint.Y() ) );
+
+  // Compute all other points
+  for ( int i = 2, n = aParametricPoints.Length(); i < n ; ++i )
+  {
+    const HYDROData_ProfileUZ::Point& aParPoint = aParametricPoints.Value( i );
+
+    double aParPointDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aParPoint.X(), 0 ) );
+    
+    double aParLen = ( aParPointDist / aParCommonDist ) * aGeoDistance;
+
+    double aRatio = aParLen / ( aGeoDistance - aParLen );
+
+    double aParX = ( aFirstPoint.X() + aRatio * aLastPoint.X() ) / ( 1 + aRatio );
+    double aParY = ( aFirstPoint.Y() + aRatio * aLastPoint.Y() ) / ( 1 + aRatio );
+
+    ProfilePoint aCompPoint( aParX, aParY, aParPoint.Y() );
+    aResPoints.Append( aCompPoint );
+  }
+
+  // Add last point as is
+  aResPoints.Append( ProfilePoint( aLastPoint.X(), aLastPoint.Y(), aLastParPoint.Y() ) );
+
+  return aResPoints;
+}
+
+void HYDROData_Profile::SetFilePath( const TCollection_AsciiString& theFilePath )
+{
+  TDataStd_AsciiString::Set( myLab.FindChild( DataTag_FilePath ), theFilePath );
+}
+
+TCollection_AsciiString HYDROData_Profile::GetFilePath() const
+{
+  TCollection_AsciiString aRes;
+
+  Handle(TDataStd_AsciiString) anAsciiStr;
+  if ( myLab.FindChild( DataTag_FilePath ).FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) )
+    aRes = anAsciiStr->Get();
+
+  return aRes;
+}
+
+bool HYDROData_Profile::ImportFromFile( const Handle(HYDROData_Document)& theDoc,
+                                        const TCollection_AsciiString&    theFileName )
+{
+  if ( theDoc.IsNull() || theFileName.IsEmpty() )
+    return false;
+
+  OSD_File aFile( theFileName );
+  if ( !aFile.IsReadable() )
+    return false;
+
+  aFile.Open( OSD_ReadOnly, OSD_Protection() );
+  if ( !aFile.IsOpen() )
+    return false;
+
+  bool aRes = true;
+
+  NCollection_Sequence<Handle(HYDROData_Profile)> aCreatedProfiles;
+
+  while ( aRes && !aFile.IsAtEnd() )
+  {
+    Handle(HYDROData_Profile) aNewProfile = 
+      Handle(HYDROData_Profile)::DownCast( theDoc->CreateObject( KIND_PROFILE ) );
+    
+    aRes = aNewProfile->ImportFromFile( aFile );
+
+    aCreatedProfiles.Append( aNewProfile );
+  }
+
+  // Close the file
+  aFile.Close();
+
+  for ( int i = 1, n = aCreatedProfiles.Length(); i < n ; ++i )
+  {
+    Handle(HYDROData_Profile) aProfile = aCreatedProfiles.Value( i );
+    if ( aRes )
+    {
+      QString aProfileName = HYDROData_Tool::GenerateObjectName( theDoc, "Profile" );
+      aProfile->SetName( aProfileName );
+
+      aProfile->SetFilePath( theFileName );
+    }
+    else
+    {
+      aProfile->Remove();
+    }
+  }
+
+  return aRes;
+}
+
+bool HYDROData_Profile::ImportFromFile( const TCollection_AsciiString& theFileName )
+{
+  // Try to open the file
+  OSD_File aFile( theFileName );
+  if ( !aFile.IsReadable() )
+    return false;
+
+  aFile.Open( OSD_ReadOnly, OSD_Protection() );
+  if ( !aFile.IsOpen() )
+    return false;
+
+  bool aRes = ImportFromFile( aFile );
+
+  // Close the file
+  aFile.Close();
+
+  if ( aRes )
+  {
+    // Update file path
+    SetFilePath( theFileName );
+  }
+
+  return aRes;
+}
+
+bool HYDROData_Profile::ImportFromFile( OSD_File& theFile )
+{
+  if ( !theFile.IsOpen() )
+    return false;
+
+  bool aRes = true;
+
+  bool anIsParametric = false;
+  bool anIsGeoref     = false;
+
+  HYDROData_ProfileUZ::PointsList aPointsUZ;
+  ProfilePoints                   aPointsXYZ;
+
+  double aPrevVal = -DBL_MAX;
+  while ( !theFile.IsAtEnd() )
+  {
+    Standard_Integer aNbRead = 0;
+    TCollection_AsciiString aLine;
+    theFile.ReadLine( aLine, 1024, aNbRead );
+
+    aLine.LeftAdjust(); aLine.RightAdjust();
+    if ( aLine.IsEmpty() )
+      continue;
+
+    TCollection_AsciiString aValX = aLine.Token( " \t", 1 );
+    TCollection_AsciiString aValY = aLine.Token( " \t", 2 );
+    TCollection_AsciiString aValZ = aLine.Token( " \t", 3 );
+
+    if ( aValX.IsEmpty() || !aValX.IsRealValue() ||
+         aValY.IsEmpty() || !aValY.IsRealValue() )
+    {
+      aRes = false;
+      break;
+    }
+
+    if ( !anIsParametric && !anIsGeoref )
+    {
+      anIsParametric = aValZ.IsEmpty();
+      anIsGeoref = !aValZ.IsEmpty();
+    }
+
+    double aCoordX = aValX.RealValue();
+    double aCoordY = aValY.RealValue();
+
+    if ( anIsParametric )
+    {
+      if ( aCoordX < aPrevVal )
+      {
+        // Move back readed line
+        theFile.Seek( -( aNbRead + 1 ), OSD_FromHere );
+        break;
+      }
+
+      HYDROData_ProfileUZ::Point aPoint( aCoordX, aCoordY );
+      aPointsUZ.Append( aPoint );
+
+      aPrevVal = aCoordX;
+    }
+    else
+    {
+      if ( aValZ.IsEmpty() || !aValZ.IsRealValue() )
+      {
+        aRes = false;
+        break;
+      }
+
+      double aCoordZ = aValZ.RealValue();
+
+      ProfilePoint aPoint( aCoordX, aCoordY, aCoordZ );
+      aPointsXYZ.Append( aPoint );
+    }
+  }
+  
+  aRes = aRes && ( anIsParametric && !aPointsUZ.IsEmpty() || 
+                   anIsGeoref && !aPointsXYZ.IsEmpty() );
+  if ( aRes )
+  {
+    // Update profile points
+    if ( anIsParametric )
+    {
+      SetParametricPoints( aPointsUZ );
+    }
+    else if ( anIsGeoref )
+    {
+      SetProfilePoints( aPointsXYZ );
+    }
+  }
+
+  return aRes;
+}
+
+
+
diff --git a/src/HYDROData/HYDROData_Profile.h b/src/HYDROData/HYDROData_Profile.h
new file mode 100644 (file)
index 0000000..775ced7
--- /dev/null
@@ -0,0 +1,224 @@
+
+#ifndef HYDROData_Profile_HeaderFile
+#define HYDROData_Profile_HeaderFile
+
+#include "HYDROData_Object.h"
+
+#include "HYDROData_ProfileUZ.h"
+
+DEFINE_STANDARD_HANDLE(HYDROData_Profile, HYDROData_Object)
+
+class gp_XYZ;
+class OSD_File;
+class Handle(HYDROData_Document);
+
+/**\class HYDROData_Profile
+ * \brief Class that stores/retreives information about the profile.
+ */
+class HYDROData_Profile : public HYDROData_Object
+{
+public:
+
+  typedef gp_XYZ                             ProfilePoint;
+  typedef NCollection_Sequence<ProfilePoint> ProfilePoints;
+
+protected:
+  /**
+   * Enumeration of tags corresponding to the persistent object parameters.
+   */
+  enum DataTag
+  {
+    DataTag_First = HYDROData_Object::DataTag_First + 100, ///< first tag, to reserve
+    DataTag_FirstPoint,       ///< first(left) point
+    DataTag_LastPoint,        ///< last(right) point
+    DataTag_ChildProfileUZ,   ///< child parametric profile
+    DataTag_FilePath          ///< profile imported file path
+  };
+
+public:
+  DEFINE_STANDARD_RTTI(HYDROData_Profile);
+
+  /**
+   * Returns the kind of this object. Must be redefined in all objects of known type.
+   */
+  HYDRODATA_EXPORT virtual const ObjectKind GetKind() const { return KIND_PROFILE; }
+
+  /**
+   * Returns the top shape of the object.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Shape GetTopShape() const;
+
+  /**
+   * Returns the 3d shape of the object.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Shape GetShape3D() const;
+
+  /**
+   * Updates profile 3D presentation.
+   * Call this method whenever you made changes in data structure.
+   * This method does not called automatically since it may take a very long time.
+   */
+  HYDRODATA_EXPORT virtual void UpdateShape3D();
+
+  /**
+   * Dump object to Python script representation.
+   */
+  HYDRODATA_EXPORT virtual QStringList DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const;
+
+
+  /**
+   * Check profile data and returns true if profile is valid.
+   * Validity is determined by:
+   *   - First(left) and Last(right) point was set
+   *   - Parametric points size is more than 1
+   */
+  HYDRODATA_EXPORT bool IsValid() const;
+
+public:
+
+  // Public methods to work with profile points.
+
+  /**
+   * Set first(left) point for profile.
+   * \param thePoint the point
+   */
+  HYDRODATA_EXPORT void SetFirstPoint( const gp_XY& thePoint );
+
+  /**
+   * Returns first(left) point of profile.
+   * \param thePoint[out] profile first point
+   * \return true if point has been set
+   */
+  HYDRODATA_EXPORT bool GetFirstPoint( gp_XY& thePoint ) const;
+
+  /**
+   * Set last(right) point for profile.
+   * \param thePoint the point
+   */
+  HYDRODATA_EXPORT void SetLastPoint( const gp_XY& thePoint );
+
+  /**
+   * Returns last(right) point of profile.
+   * \param thePoint[out] profile last point
+   * \return true if point has been set
+   */
+  HYDRODATA_EXPORT bool GetLastPoint( gp_XY& thePoint ) const;
+
+
+  /**
+   * Returns object which store parametric presentation of profile points.
+   * \return profile U,Z
+   */
+  HYDRODATA_EXPORT Handle(HYDROData_ProfileUZ) GetProfileUZ( const bool theIsCreate = true ) const;
+
+
+  /**
+   * Return number of profile points.
+   * \return number of points
+   */
+  HYDRODATA_EXPORT int NbPoints() const;
+
+  /**
+   * Remove all profile points.
+   */
+  HYDRODATA_EXPORT void RemovePoints();
+
+
+  /**
+   * Replace current profile parametric points by new one.
+   * \param thePoints the list with new points in parametric form
+   */
+  HYDRODATA_EXPORT void SetParametricPoints( const HYDROData_ProfileUZ::PointsList& thePoints );
+
+  /**
+   * Returns profile points in parametric form.
+   * \return points list
+   */
+  HYDRODATA_EXPORT HYDROData_ProfileUZ::PointsList GetParametricPoints() const;
+
+
+  /**
+   * Replace current profile points by new one.
+   * First and last points will be automatically updated.
+   * \param thePoints the list with new profile points
+   */
+  HYDRODATA_EXPORT void SetProfilePoints( const ProfilePoints& thePoints );
+
+  /**
+   * Returns profile points.
+   * Empty sequence is returned if first or last point was not set.
+   * \return profile points list
+   */
+  HYDRODATA_EXPORT ProfilePoints GetProfilePoints() const;
+
+
+public:
+  // Public methods to work with files.
+
+  /**
+   * Stores the profile file path
+   * \param theFilePath profile file path
+   */
+  HYDRODATA_EXPORT void SetFilePath( const TCollection_AsciiString& theFilePath );
+
+  /**
+   * Returns uploaded profile file path
+   */
+  HYDRODATA_EXPORT TCollection_AsciiString  GetFilePath() const;
+
+  /**
+   * Imports Profile data from file. The supported file types:
+   *  - parametric presentation of profile (2 points in line U,Z)
+   *  - georeferenced presentation of profile (3 points in line X,Y,Z)
+   * Create as many objects as many profiles in the file are defined.
+   * \param theFileName the path to file
+   * \return \c true if file has been successfully read
+   */
+  HYDRODATA_EXPORT static bool ImportFromFile( const Handle(HYDROData_Document)& theDoc,
+                                               const TCollection_AsciiString&    theFileName );
+
+  /**
+   * Imports Profile data from file.
+   * \param theFileName the path to file
+   * \return \c true if file has been successfully read
+   */
+  HYDRODATA_EXPORT virtual bool ImportFromFile( const TCollection_AsciiString& theFileName );
+
+  /**
+   * Imports Profile data from file. 
+   * \param theFile file to read
+   * \return \c true if file has been successfully read
+   */
+  HYDRODATA_EXPORT virtual bool ImportFromFile( OSD_File& theFile );
+
+private:
+
+  /**
+   * Imports Profile data from parametric file.
+   */
+  bool importParametricFile( OSD_File&                        theFile,
+                             HYDROData_ProfileUZ::PointsList& thePoints );
+
+  /**
+   * Imports Profile data from Georeferenced file.
+   */
+  bool importGeoreferencedFile( OSD_File&      theFile,
+                                ProfilePoints& thePoints );
+
+protected:
+
+  friend class HYDROData_Iterator;
+
+  /**
+   * Creates new object in the internal data structure. Use higher level objects 
+   * to create objects with real content.
+   */
+  HYDROData_Profile();
+
+  /**
+   * Destructs properties of the object and object itself, removes it from the document.
+   */
+  ~HYDROData_Profile();
+};
+
+#endif
diff --git a/src/HYDROData/HYDROData_ProfileUZ.cxx b/src/HYDROData/HYDROData_ProfileUZ.cxx
new file mode 100755 (executable)
index 0000000..36ce31c
--- /dev/null
@@ -0,0 +1,178 @@
+
+#include "HYDROData_ProfileUZ.h"
+
+#include "HYDROData_Tool.h"
+
+#include <gp_XY.hxx>
+
+#include <TColStd_ListIteratorOfListOfReal.hxx>
+
+#include <TDataStd_RealList.hxx>
+
+#include <TopoDS_Wire.hxx>
+
+
+IMPLEMENT_STANDARD_HANDLE(HYDROData_ProfileUZ, HYDROData_IPolyline)
+IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ProfileUZ, HYDROData_IPolyline)
+
+HYDROData_ProfileUZ::HYDROData_ProfileUZ()
+: HYDROData_IPolyline()
+{
+}
+
+HYDROData_ProfileUZ::~HYDROData_ProfileUZ()
+{
+}
+
+TopoDS_Wire HYDROData_ProfileUZ::GetWire() const
+{
+  // TODO
+  return TopoDS_Wire();
+}
+
+int HYDROData_ProfileUZ::NbSections() const
+{
+  return 1;
+}
+
+void HYDROData_ProfileUZ::AddSection( const bool /*theIsClosed*/ )
+{
+}
+
+bool HYDROData_ProfileUZ::IsClosedSection( const int /*theSectionIndex*/ ) const
+{
+  return false;
+}
+
+void HYDROData_ProfileUZ::RemoveSection( const int /*theSectionIndex*/ )
+{
+  RemoveSections();
+}
+
+void HYDROData_ProfileUZ::RemoveSections()
+{
+  removePointsLists( 0 );
+}
+
+void HYDROData_ProfileUZ::AddPoint( const int    /*theSectionIndex*/,
+                                    const Point& thePoint,
+                                    const int    thePointIndex )
+{
+  double aNewCoordU = thePoint.X();
+  double aNewCoordZ = thePoint.Y();
+
+  Handle(TDataStd_RealList) aListU, aListZ;
+  getPointsLists( 0, aListU, aListZ );
+
+  if ( aListU->IsEmpty() || aNewCoordU > aListU->Last() )
+  {
+    aListU->Append( aNewCoordU );
+    aListZ->Append( aNewCoordZ );
+    return;
+  }
+  else if ( aNewCoordU < aListU->First() )
+  {
+    aListU->Prepend( aNewCoordU );
+    aListZ->Prepend( aNewCoordZ );
+    return;
+  }
+
+  TColStd_ListOfReal anOldListU;
+  anOldListU = aListU->List();
+
+  TColStd_ListOfReal anOldListZ;
+  anOldListZ = aListZ->List();
+
+  // Crsat new lists
+  removePointsLists( 0 );
+  getPointsLists( 0, aListU, aListZ );
+
+  bool anIsInserted = false;
+  TColStd_ListIteratorOfListOfReal anIterU( anOldListU );
+  TColStd_ListIteratorOfListOfReal anIterZ( anOldListZ );
+  for ( ; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next() )
+  {
+    double aCoordU = anIterU.Value();
+    double aCoordZ = anIterZ.Value();
+
+    if ( !anIsInserted )
+    {
+      if ( ValuesEquals( aNewCoordU, aCoordU ) )
+      {
+        // Just update Z value
+        aCoordZ = aNewCoordZ;
+        anIsInserted = true;
+      }
+      else if ( aNewCoordU < aCoordU )
+      {
+        // Insert new point
+        aListU->Append( aNewCoordU );
+        aListZ->Append( aNewCoordZ );
+        anIsInserted = true;
+      }
+    }
+
+    aListU->Append( aCoordU );
+    aListZ->Append( aCoordZ );
+  }
+}
+
+void HYDROData_ProfileUZ::SetPoint( const int    theSectionIndex,
+                                    const int    /*thePointIndex*/,
+                                    const Point& thePoint )
+{
+  AddPoint( theSectionIndex, thePoint );
+}
+
+void HYDROData_ProfileUZ::RemovePoint( const int /*theSectionIndex*/,
+                                       const int thePointIndex )
+{
+  Handle(TDataStd_RealList) aListU, aListZ;
+  getPointsLists( 0, aListU, aListZ, false );
+  if ( aListU.IsNull() || aListZ.IsNull() || aListU->IsEmpty() )
+    return;
+
+  TColStd_ListOfReal anOldListU;
+  anOldListU = aListU->List();
+
+  TColStd_ListOfReal anOldListZ;
+  anOldListZ = aListZ->List();
+
+  // Creat new lists
+  removePointsLists( 0 );
+  getPointsLists( 0, aListU, aListZ );
+
+  bool anIsInserted = false;
+  TColStd_ListIteratorOfListOfReal anIterU( anOldListU );
+  TColStd_ListIteratorOfListOfReal anIterZ( anOldListZ );
+  for ( int i = 0; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next(), ++i )
+  {
+    if ( i == thePointIndex )
+      continue; // skip index to remove
+
+    aListU->Append( anIterU.Value() );
+    aListZ->Append( anIterZ.Value() );
+  }
+}
+
+HYDROData_ProfileUZ::PointsList HYDROData_ProfileUZ::GetPoints( const int /*theSectionIndex*/ ) const
+{
+  PointsList aResList;
+
+  Handle(TDataStd_RealList) aListU, aListZ;
+  getPointsLists( 0, aListU, aListZ, false );
+  if ( aListU.IsNull() || aListZ.IsNull() )
+    return aResList;
+
+  TColStd_ListIteratorOfListOfReal anIterU( aListU->List() );
+  TColStd_ListIteratorOfListOfReal anIterZ( aListZ->List() );
+  for ( ; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next() )
+  {
+    Point aPoint( anIterU.Value(), anIterZ.Value() );
+    aResList.Append( aPoint );
+  }
+
+  return aResList;
+}
+
+
diff --git a/src/HYDROData/HYDROData_ProfileUZ.h b/src/HYDROData/HYDROData_ProfileUZ.h
new file mode 100644 (file)
index 0000000..9b86029
--- /dev/null
@@ -0,0 +1,123 @@
+
+#ifndef HYDROData_ProfileUZ_HeaderFile
+#define HYDROData_ProfileUZ_HeaderFile
+
+#include "HYDROData_IPolyline.h"
+
+DEFINE_STANDARD_HANDLE(HYDROData_ProfileUZ, HYDROData_IPolyline)
+
+/**\class HYDROData_ProfileUZ
+ * \brief Class that stores/retreives information about the 
+ *        parametric profile points.
+ */
+class HYDROData_ProfileUZ : public HYDROData_IPolyline
+{
+protected:
+  /**
+   * Enumeration of tags corresponding to the persistent object parameters.
+   */
+  enum DataTag
+  {
+    DataTag_First = HYDROData_IPolyline::DataTag_First + 100, ///< first tag, to reserve
+  };
+
+public:
+  DEFINE_STANDARD_RTTI(HYDROData_ProfileUZ);
+
+
+  /**
+   * Returns the kind of this object. Must be redefined in all objects of known type.
+   */
+  HYDRODATA_EXPORT virtual const ObjectKind GetKind() const {return KIND_PROFILEUZ;}
+
+public:
+
+  /**
+   * Returns the 3D presentation of all points.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Wire GetWire() const;
+
+
+  /**
+   * Returns number of sections.
+   */
+  HYDRODATA_EXPORT virtual int NbSections() const;
+
+  /**
+   * Adds new one section.
+   * \param theIsClosed flag indicates type of polyline
+   */
+  HYDRODATA_EXPORT virtual void AddSection( const bool theIsClosed );
+
+  /**
+   * Returns true if section with given index is closed.
+   * \param theSectionIndex index of section
+   */
+  HYDRODATA_EXPORT virtual bool IsClosedSection( const int theSectionIndex ) const;
+
+  /**
+   * Removes section with given index.
+   * \param theSectionIndex index of section
+   */
+  HYDRODATA_EXPORT virtual void RemoveSection( const int theSectionIndex );
+
+  /**
+   * Removes all sections.
+   */
+  HYDRODATA_EXPORT virtual void RemoveSections();
+
+
+  /**
+   * Adds new point for section with index "theSectionIndex".
+   * \param theSectionIndex index of section
+   * \param thePoint point to add
+   * \param theBeforeIndex if not equal -1 then insert point in this pos
+   */
+  HYDRODATA_EXPORT virtual void AddPoint( const int    theSectionIndex,
+                                          const Point& thePoint,
+                                          const int    thePointIndex = -1 );
+
+  /**
+   * Replaces point for section with index "theSectionIndex".
+   * \param theSectionIndex index of section
+   * \param thePointIndex index of point to replace
+   * \param thePoint new point
+   */
+  HYDRODATA_EXPORT virtual void SetPoint( const int    theSectionIndex,
+                                          const int    thePointIndex,
+                                          const Point& thePoint );
+
+  /**
+   * Removes point from section with index "theSectionIndex".
+   * \param theSectionIndex index of section
+   * \param thePointIndex index of point
+   */
+  HYDRODATA_EXPORT virtual void RemovePoint( const int theSectionIndex,
+                                             const int thePointIndex );
+
+
+  /**
+   * Returns list of points.
+   * \param theSectionIndex if not equal -1 then list of points returned
+   *                        only for section with this index
+   * \return list of points
+   */
+  HYDRODATA_EXPORT virtual PointsList GetPoints( const int theSectionIndex = -1 ) const;
+
+protected:
+
+  friend class HYDROData_Iterator;
+
+  /**
+   * Creates new object in the internal data structure. Use higher level objects 
+   * to create objects with real content.
+   */
+  HYDROData_ProfileUZ();
+
+  /**
+   * Destructs properties of the object and object itself, removes it from the document.
+   */
+  ~HYDROData_ProfileUZ();
+};
+
+#endif
diff --git a/src/HYDROData/test_HYDROData_Profile.cxx b/src/HYDROData/test_HYDROData_Profile.cxx
new file mode 100755 (executable)
index 0000000..69c8e79
--- /dev/null
@@ -0,0 +1,147 @@
+
+#include <test_HYDROData_Profile.h>
+
+#include <HYDROData_Document.h>
+#include <HYDROData_Tool.h>
+#include <HYDROData_Profile.h>
+#include <HYDROData_Iterator.h>
+
+#include <TopoDS_Shape.hxx>
+
+#include <gp_XY.hxx>
+#include <gp_XYZ.hxx>
+
+#include <QDir>
+#include <QFile>
+#include <QTextStream>
+
+bool test_HYDROData_Profile::createTestFile( const QString& theFileName,
+                                             const bool     theIsParametric )
+{
+  QFile aTmpFile( theFileName );
+  if ( !aTmpFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
+    return false;
+
+  if ( theIsParametric )
+  {
+    QTextStream anOutStream( &aTmpFile );
+    
+    anOutStream << "0      182.15 \n";
+    anOutStream << "4      181.95 \n";
+    anOutStream << "10.18  181.63 \n";
+    anOutStream << "14.75  179.27 \n";
+    anOutStream << "19.75  178.87 \n";
+
+    anOutStream << "\n";
+
+    anOutStream << "-5   50    \n";
+    anOutStream << "0    15    \n";
+    anOutStream << "10.1 10    \n";
+    anOutStream << "20   20    \n";
+    anOutStream << "250  0.005 \n";
+  }
+  else
+  {
+    QTextStream anOutStream( &aTmpFile );
+
+    anOutStream << "1040499.17 6788618.13 182.15 \n";
+    anOutStream << "1040503.12 6788618.79 181.95 \n";
+    anOutStream << "1040509.21 6788619.81 181.63 \n";
+    anOutStream << "1040513.72 6788620.56 179.27 \n";
+    anOutStream << "1040518.65 6788621.38 178.87 \n";
+  }
+
+  aTmpFile.close();
+
+  return true;
+}
+
+void test_HYDROData_Profile::testFileImport()
+{
+  Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( 1 );
+
+  QString aParamFileName = QDir::tempPath() + QDir::separator() + "parametric.pa";
+  QString aGeorefFileName = QDir::tempPath() + QDir::separator() + "georef.pa";
+  if ( !createTestFile( aParamFileName, true ) || !createTestFile( aGeorefFileName, false ) )
+    return; // No file has been created
+
+  TCollection_AsciiString aFileName( aParamFileName.toStdString().c_str() );
+
+  CPPUNIT_ASSERT( HYDROData_Profile::ImportFromFile( aDoc, aFileName ) );
+
+  int aProfileCount = 0;
+  HYDROData_Iterator aDocIter( aDoc, KIND_PROFILE );
+  for ( ; aDocIter.More(); aDocIter.Next() )
+  {
+    Handle(HYDROData_Profile) aProfile = 
+      Handle(HYDROData_Profile)::DownCast( aDocIter.Current() );
+    if ( aProfile.IsNull() )
+      continue;
+    
+    CPPUNIT_ASSERT( aProfile->IsValid() == false );
+    CPPUNIT_ASSERT( aProfile->NbPoints() == 5 );
+    
+    aProfileCount++;
+  }
+
+  CPPUNIT_ASSERT( aProfileCount == 2 );
+
+  Handle(HYDROData_Profile) aGeorefProfile = 
+    Handle(HYDROData_Profile)::DownCast( aDoc->CreateObject( KIND_PROFILE ) );
+
+  aFileName = TCollection_AsciiString( aGeorefFileName.toStdString().c_str() );
+  CPPUNIT_ASSERT( aGeorefProfile->ImportFromFile( aFileName ) );
+
+  // Check validity of imported profile
+  CPPUNIT_ASSERT( aGeorefProfile->IsValid() );
+
+  CPPUNIT_ASSERT( aGeorefProfile->GetTopShape().IsNull() == false );
+
+  aGeorefProfile->UpdateShape3D();
+  CPPUNIT_ASSERT( aGeorefProfile->GetShape3D().IsNull() == false );
+
+  HYDROData_Profile::ProfilePoints aProfilePoints = aGeorefProfile->GetProfilePoints();
+  CPPUNIT_ASSERT( aProfilePoints.Length() == 5 );
+
+  HYDROData_Profile::ProfilePoint aProfilePoint = aProfilePoints.Value( 3 );
+  CPPUNIT_ASSERT( ValuesEquals( aProfilePoint.X(), 1040509.21 ) );
+  CPPUNIT_ASSERT( ValuesEquals( aProfilePoint.Y(), 6788619.81 ) );
+  CPPUNIT_ASSERT( ValuesEquals( aProfilePoint.Z(), 181.63 ) );
+
+  aDoc->Close();
+}
+
+
+void test_HYDROData_Profile::testCopy()
+{
+  Handle(HYDROData_Document) aDoc = HYDROData_Document::Document(1);
+  
+  Handle(HYDROData_Profile) aProfile1 = 
+    Handle(HYDROData_Profile)::DownCast( aDoc->CreateObject( KIND_PROFILE ) );
+
+  QString aFileName = QDir::tempPath() + QDir::separator() + "georef.pa";
+
+  bool anIsFileCreated = createTestFile( aFileName, false );
+  
+  if ( anIsFileCreated )
+  {
+    TCollection_AsciiString anAsciiFileName( aFileName.toStdString().c_str() );
+    CPPUNIT_ASSERT( aProfile1->ImportFromFile( anAsciiFileName ) );
+
+    CPPUNIT_ASSERT( aProfile1->IsValid() );
+    CPPUNIT_ASSERT( aProfile1->NbPoints() == 5 );
+  }
+
+  Handle(HYDROData_Profile) aProfile2 = 
+    Handle(HYDROData_Profile)::DownCast( aDoc->CreateObject( KIND_PROFILE ) );
+
+  aProfile1->CopyTo( aProfile2 );
+
+  if ( anIsFileCreated )
+  {
+    CPPUNIT_ASSERT( aProfile2->IsValid() );
+    CPPUNIT_ASSERT( aProfile2->NbPoints() == 5 );
+  }
+
+  aDoc->Close();
+}
diff --git a/src/HYDROData/test_HYDROData_Profile.h b/src/HYDROData/test_HYDROData_Profile.h
new file mode 100755 (executable)
index 0000000..f59ea99
--- /dev/null
@@ -0,0 +1,33 @@
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class Handle_HYDROData_Profile;
+class QString;
+
+class test_HYDROData_Profile : public CppUnit::TestFixture {
+  CPPUNIT_TEST_SUITE(test_HYDROData_Profile);
+  CPPUNIT_TEST(testFileImport);
+  CPPUNIT_TEST(testCopy);
+  CPPUNIT_TEST_SUITE_END();
+
+private:
+
+  static bool                             createTestFile( const QString& theFileName,
+                                                          const bool     theIsParametric );
+
+public:
+
+  void                                    setUp() {}
+
+  void                                    tearDown() {}
+
+  // checks file importing information
+  void                                    testFileImport();
+
+  // checks the copy/paste mechanism
+  void                                    testCopy();
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test_HYDROData_Profile);
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_HYDROData_Profile, "HYDROData_Profile");