]> SALOME platform Git repositories - modules/hydro.git/commitdiff
Salome HOME
Altitude object implemented for stream (Feature #260).
authoradv <adv@opencascade.com>
Wed, 25 Dec 2013 08:27:18 +0000 (08:27 +0000)
committeradv <adv@opencascade.com>
Wed, 25 Dec 2013 08:27:18 +0000 (08:27 +0000)
src/HYDROData/HYDROData_Stream.cxx
src/HYDROData/HYDROData_Stream.h
src/HYDROData/HYDROData_StreamAltitude.cxx
src/HYDROData/HYDROData_StreamAltitude.h

index 5c50dc565671a6b569528a0d1fc36ce727237b8e..9aa3d2354deeac809724251d2732cfea92240dea 100644 (file)
@@ -6,6 +6,7 @@
 #include "HYDROData_Profile.h"
 #include "HYDROData_ShapesGroup.h"
 #include "HYDROData_ShapesTool.h"
+#include "HYDROData_IAltitudeObject.h"
 
 #include <TDataStd_RealArray.hxx>
 
@@ -147,6 +148,161 @@ void HYDROData_Stream::Update()
   UpdatePrs();
 }
 
+void HYDROData_Stream::UpdatePrs()
+{
+  HYDROData_NaturalObject::Update();
+
+  Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
+  HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
+  if ( aHydAxis.IsNull() || aRefProfiles.Length() < 2 )
+    return; 
+  bool anIsFirst = true;
+  gp_Pnt aPrevFirstPoint, aPrevLastPoint;
+  Handle(TColgp_HArray1OfPnt) anArrayOfFPnt    = new TColgp_HArray1OfPnt(1, aRefProfiles.Length());
+  Handle(TColgp_HArray1OfPnt) anArrayOfLPnt    = new TColgp_HArray1OfPnt(1, aRefProfiles.Length());  
+  TopTools_Array1OfShape anArrOfProfiles(1, aRefProfiles.Length());
+  TopTools_Array1OfShape anArrOf2DProfiles(1, aRefProfiles.Length());
+
+  // Pre-processing
+  HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
+  for (int i=1 ; anIter.More(); anIter.Next(),i++ )
+  {
+    Handle(HYDROData_Profile) aProfile =
+      Handle(HYDROData_Profile)::DownCast( anIter.Value() );
+    if ( aProfile.IsNull() )
+      continue;    
+    const TopoDS_Shape& aProf3d = aProfile->GetShape3D();
+    gp_XY aPnt1, aPnt2;
+    if ( !aProfile->GetLeftPoint( aPnt1 ) || !aProfile->GetRightPoint( aPnt2 ) )
+      continue;
+    anArrOfProfiles.SetValue(i,aProfile->GetShape3D());//aProfile->GetTopShape();
+    anArrOf2DProfiles.SetValue(i,aProfile->GetTopShape());
+
+    gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 ), aCurFP;
+    gp_Pnt aCurLastPoint(  aPnt2.X(), aPnt2.Y(), 0 ), aCurLP;
+    TopoDS_Vertex aV1, aV2;
+    TopExp::Vertices(TopoDS::Wire(aProf3d), aV1, aV2);
+       gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
+    if(aP1.X() == aPnt1.X() && aP1.Y() == aPnt1.Y())
+      aCurFP = aP1;
+    else
+      aCurLP = aP1;
+    aP1 = BRep_Tool::Pnt(aV2);
+    if(aP1.X() == aPnt2.X() && aP1.Y() == aPnt2.Y())
+      aCurLP = aP1;
+    else
+      aCurFP = aP1;
+    anArrayOfFPnt->SetValue(i,aCurFP);
+    anArrayOfLPnt->SetValue(i,aCurLP);
+  }
+
+  // Construct of the 3D presentation
+  Handle(Geom_BSplineCurve) aBSpline = buildInterpolationCurve (anArrayOfFPnt);
+  if(aBSpline.IsNull())
+    return;
+  TopoDS_Edge anEdgLeft, anEdgRight;
+  BRepBuilderAPI_MakeEdge aMakeEdge(aBSpline);
+  if(aMakeEdge.IsDone()) 
+    anEdgLeft = aMakeEdge.Edge();
+  if(anEdgLeft.IsNull())
+    return;
+  aBSpline.Nullify();
+  aBSpline = buildInterpolationCurve (anArrayOfLPnt);  
+  if(aBSpline.IsNull())
+    return; 
+  aMakeEdge.Init(aBSpline);
+  if(aMakeEdge.IsDone()) 
+    anEdgRight = aMakeEdge.Edge();
+  if(anEdgRight.IsNull())
+    return;
+  BRep_Builder aBB;
+  TopoDS_Compound aCmp;
+  aBB.MakeCompound(aCmp);
+  anIter.Init( aRefProfiles );
+  for (int i=1 ; i < anArrOfProfiles.Length() +1; i++ )  
+    aBB.Add(aCmp, anArrOfProfiles.Value(i));
+  aBB.Add(aCmp,anEdgLeft);
+  aBB.Add(aCmp,anEdgRight);
+  BRepCheck_Analyzer aCh(aCmp);
+  if(aCh.IsValid())
+    SetShape3D(aCmp);
+#ifdef DEB_UPDATE
+  else {
+    BRepTools::Write(aCmp, "str3d.brep");
+    SetShape3D(aCmp);
+  }
+#endif
+
+  // Construct the top presentation
+  for(int i=1;i<= anArrayOfLPnt->Length();i++) {
+      gp_Pnt aPnt = anArrayOfFPnt->Value(i);
+      aPnt.SetZ(.0); // make 2d
+      anArrayOfFPnt->SetValue(i, aPnt);
+      aPnt = anArrayOfLPnt->Value(i);
+      aPnt.SetZ(.0);
+      anArrayOfLPnt->SetValue(i, aPnt);
+  }
+  aBSpline.Nullify();
+  aBSpline = buildInterpolationCurve (anArrayOfFPnt);  
+  if(aBSpline.IsNull())
+    return; 
+  aMakeEdge.Init(aBSpline);
+  if(aMakeEdge.IsDone()) 
+      anEdgLeft = aMakeEdge.Edge();
+  aBSpline.Nullify();
+  aBSpline = buildInterpolationCurve (anArrayOfLPnt);  
+  if(aBSpline.IsNull())
+    return; 
+  aMakeEdge.Init(aBSpline);
+  if(aMakeEdge.IsDone()) 
+    anEdgRight = aMakeEdge.Edge();
+  if(anEdgRight.IsNull())
+    return;
+  BRepBuilderAPI_MakeEdge aMakeEdge2(anArrayOfFPnt->Value(1),anArrayOfLPnt->Value(1));
+  TopoDS_Edge aBotEdge, aTopEdge;
+  if(aMakeEdge2.IsDone()) 
+    aBotEdge = aMakeEdge2.Edge();
+  BRepBuilderAPI_MakeEdge aMakeEdge3(anArrayOfFPnt->Value(anArrayOfFPnt->Length()),anArrayOfLPnt->Value(anArrayOfLPnt->Length()));
+  if(aMakeEdge3.IsDone()) 
+    aTopEdge = aMakeEdge3.Edge();
+
+  BRepBuilderAPI_MakeWire aMakeWire( aBotEdge, anEdgLeft, aTopEdge,anEdgRight);
+  TopoDS_Wire aSectProfileWire;
+  if(aMakeWire.IsDone())
+    aSectProfileWire = aMakeWire.Wire();
+  BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
+  TopoDS_Face aFace;
+  aMakeFace.Build();
+  if( aMakeFace.IsDone() )
+    aFace = aMakeFace.Face();
+  aCmp.Nullify();
+  aBB.MakeCompound(aCmp);
+  aBB.Add(aCmp,aFace);
+  for(int i=1;i <= anArrOf2DProfiles.Length(); i++)
+    aBB.Add(aCmp,anArrOf2DProfiles.Value(i));
+  aCh.Init(aCmp);
+  if(aCh.IsValid())
+    SetTopShape(aCmp);
+#ifdef DEB_UPDATE
+  else {
+    BRepTools::Write(aCmp, "str2d.brep");
+    SetTopShape(aCmp);
+  }
+#endif 
+
+  // Create the stream groups
+  createGroupObjects();
+
+  // This peace of code is for testing of functionality of altitude,
+  // will be removed by adv when testing will be finished
+  Handle(HYDROData_IAltitudeObject) anAltObj = GetAltitudeObject();
+  gp_XY aTestPnt( 5, 0 );
+  anAltObj->GetAltitudeForPoint( aTestPnt );
+  // End of test code
+
+}
+
 QColor HYDROData_Stream::DefaultFillingColor()
 {
   return QColor( Qt::green );
@@ -171,6 +327,51 @@ bool HYDROData_Stream::IsValidAsAxis( const Handle(HYDROData_PolylineXY)& theHyd
   return true;
 }
 
+TopoDS_Shape getShapeFromGroup( const HYDROData_SequenceOfObjects& theGroups,
+                                const int                          theGroupId )
+{
+  TopoDS_Shape aResShape;
+  if ( theGroups.Length() != 4 )
+    return aResShape;
+
+  Handle(HYDROData_ShapesGroup) aGroup =
+    Handle(HYDROData_ShapesGroup)::DownCast( theGroups.Value( theGroupId ) );
+  if ( aGroup.IsNull() )
+    return aResShape;
+
+  TopTools_SequenceOfShape aGroupShapes;
+  aGroup->GetShapes( aGroupShapes );
+
+  if ( !aGroupShapes.IsEmpty() )
+    aResShape = aGroupShapes.First();
+
+  return aResShape;
+}
+
+TopoDS_Shape HYDROData_Stream::GetLeftShape() const
+{
+  HYDROData_SequenceOfObjects aGroups = GetGroups();
+  return getShapeFromGroup( aGroups, 1 );
+}
+
+TopoDS_Shape HYDROData_Stream::GetRightShape() const
+{
+  HYDROData_SequenceOfObjects aGroups = GetGroups();
+  return getShapeFromGroup( aGroups, 2 );
+}
+
+TopoDS_Shape HYDROData_Stream::GetInletShape() const
+{
+  HYDROData_SequenceOfObjects aGroups = GetGroups();
+  return getShapeFromGroup( aGroups, 3 );
+}
+
+TopoDS_Shape HYDROData_Stream::GetOutletShape() const
+{
+  HYDROData_SequenceOfObjects aGroups = GetGroups();
+  return getShapeFromGroup( aGroups, 4 );
+}
+
 QColor HYDROData_Stream::getDefaultFillingColor() const
 {
   return DefaultFillingColor();
@@ -774,150 +975,3 @@ void HYDROData_Stream::removeParameter( const int& theIndex )
 
   setParametersArray( aNewArr );
 }
-
-void HYDROData_Stream::UpdatePrs()
-{
-  HYDROData_NaturalObject::Update();
-
-  Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
-  HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
-  if ( aHydAxis.IsNull() || aRefProfiles.Length() < 2 )
-    return; 
-  bool anIsFirst = true;
-  gp_Pnt aPrevFirstPoint, aPrevLastPoint;
-  Handle(TColgp_HArray1OfPnt) anArrayOfFPnt    = new TColgp_HArray1OfPnt(1, aRefProfiles.Length());
-  Handle(TColgp_HArray1OfPnt) anArrayOfLPnt    = new TColgp_HArray1OfPnt(1, aRefProfiles.Length());  
-  TopTools_Array1OfShape anArrOfProfiles(1, aRefProfiles.Length());
-  TopTools_Array1OfShape anArrOf2DProfiles(1, aRefProfiles.Length());
-
-  // Pre-processing
-  HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
-  for (int i=1 ; anIter.More(); anIter.Next(),i++ )
-  {
-    Handle(HYDROData_Profile) aProfile =
-      Handle(HYDROData_Profile)::DownCast( anIter.Value() );
-    if ( aProfile.IsNull() )
-      continue;    
-    const TopoDS_Shape& aProf3d = aProfile->GetShape3D();
-    gp_XY aPnt1, aPnt2;
-    if ( !aProfile->GetLeftPoint( aPnt1 ) || !aProfile->GetRightPoint( aPnt2 ) )
-      continue;
-    anArrOfProfiles.SetValue(i,aProfile->GetShape3D());//aProfile->GetTopShape();
-    anArrOf2DProfiles.SetValue(i,aProfile->GetTopShape());
-
-    gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 ), aCurFP;
-    gp_Pnt aCurLastPoint(  aPnt2.X(), aPnt2.Y(), 0 ), aCurLP;
-    TopoDS_Vertex aV1, aV2;
-    TopExp::Vertices(TopoDS::Wire(aProf3d), aV1, aV2);
-       gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
-    if(aP1.X() == aPnt1.X() && aP1.Y() == aPnt1.Y())
-      aCurFP = aP1;
-    else
-      aCurLP = aP1;
-    aP1 = BRep_Tool::Pnt(aV2);
-    if(aP1.X() == aPnt2.X() && aP1.Y() == aPnt2.Y())
-      aCurLP = aP1;
-    else
-      aCurFP = aP1;
-    anArrayOfFPnt->SetValue(i,aCurFP);
-    anArrayOfLPnt->SetValue(i,aCurLP);
-  }
-
-  // Construct of the 3D presentation
-  Handle(Geom_BSplineCurve) aBSpline = buildInterpolationCurve (anArrayOfFPnt);
-  if(aBSpline.IsNull())
-    return;
-  TopoDS_Edge anEdgLeft, anEdgRight;
-  BRepBuilderAPI_MakeEdge aMakeEdge(aBSpline);
-  if(aMakeEdge.IsDone()) 
-    anEdgLeft = aMakeEdge.Edge();
-  if(anEdgLeft.IsNull())
-    return;
-  aBSpline.Nullify();
-  aBSpline = buildInterpolationCurve (anArrayOfLPnt);  
-  if(aBSpline.IsNull())
-    return; 
-  aMakeEdge.Init(aBSpline);
-  if(aMakeEdge.IsDone()) 
-    anEdgRight = aMakeEdge.Edge();
-  if(anEdgRight.IsNull())
-    return;
-  BRep_Builder aBB;
-  TopoDS_Compound aCmp;
-  aBB.MakeCompound(aCmp);
-  anIter.Init( aRefProfiles );
-  for (int i=1 ; i < anArrOfProfiles.Length() +1; i++ )  
-    aBB.Add(aCmp, anArrOfProfiles.Value(i));
-  aBB.Add(aCmp,anEdgLeft);
-  aBB.Add(aCmp,anEdgRight);
-  BRepCheck_Analyzer aCh(aCmp);
-  if(aCh.IsValid())
-    SetShape3D(aCmp);
-#ifdef DEB_UPDATE
-  else {
-    BRepTools::Write(aCmp, "str3d.brep");
-    SetShape3D(aCmp);
-  }
-#endif
-
-  // Construct the top presentation
-  for(int i=1;i<= anArrayOfLPnt->Length();i++) {
-      gp_Pnt aPnt = anArrayOfFPnt->Value(i);
-      aPnt.SetZ(.0); // make 2d
-      anArrayOfFPnt->SetValue(i, aPnt);
-      aPnt = anArrayOfLPnt->Value(i);
-      aPnt.SetZ(.0);
-      anArrayOfLPnt->SetValue(i, aPnt);
-  }
-  aBSpline.Nullify();
-  aBSpline = buildInterpolationCurve (anArrayOfFPnt);  
-  if(aBSpline.IsNull())
-    return; 
-  aMakeEdge.Init(aBSpline);
-  if(aMakeEdge.IsDone()) 
-      anEdgLeft = aMakeEdge.Edge();
-  aBSpline.Nullify();
-  aBSpline = buildInterpolationCurve (anArrayOfLPnt);  
-  if(aBSpline.IsNull())
-    return; 
-  aMakeEdge.Init(aBSpline);
-  if(aMakeEdge.IsDone()) 
-    anEdgRight = aMakeEdge.Edge();
-  if(anEdgRight.IsNull())
-    return;
-  BRepBuilderAPI_MakeEdge aMakeEdge2(anArrayOfFPnt->Value(1),anArrayOfLPnt->Value(1));
-  TopoDS_Edge aBotEdge, aTopEdge;
-  if(aMakeEdge2.IsDone()) 
-    aBotEdge = aMakeEdge2.Edge();
-  BRepBuilderAPI_MakeEdge aMakeEdge3(anArrayOfFPnt->Value(anArrayOfFPnt->Length()),anArrayOfLPnt->Value(anArrayOfLPnt->Length()));
-  if(aMakeEdge3.IsDone()) 
-    aTopEdge = aMakeEdge3.Edge();
-
-  BRepBuilderAPI_MakeWire aMakeWire( aBotEdge, anEdgLeft, aTopEdge,anEdgRight);
-  TopoDS_Wire aSectProfileWire;
-  if(aMakeWire.IsDone())
-    aSectProfileWire = aMakeWire.Wire();
-  BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
-  TopoDS_Face aFace;
-  aMakeFace.Build();
-  if( aMakeFace.IsDone() )
-    aFace = aMakeFace.Face();
-  aCmp.Nullify();
-  aBB.MakeCompound(aCmp);
-  aBB.Add(aCmp,aFace);
-  for(int i=1;i <= anArrOf2DProfiles.Length(); i++)
-    aBB.Add(aCmp,anArrOf2DProfiles.Value(i));
-  aCh.Init(aCmp);
-  if(aCh.IsValid())
-    SetTopShape(aCmp);
-#ifdef DEB_UPDATE
-  else {
-    BRepTools::Write(aCmp, "str2d.brep");
-    SetTopShape(aCmp);
-  }
-#endif 
-
-  // Create the stream groups
-  createGroupObjects();
-}
\ No newline at end of file
index 0b57d7076abf6c0385e6857fbb7d3ec65c5d1b65..fd340d335c0296bb1ef8d44fd4b1a38f9c8c9929 100644 (file)
@@ -84,8 +84,32 @@ public:
   HYDRODATA_EXPORT static bool IsValidAsAxis( const Handle(HYDROData_PolylineXY)& theAxis );
 
 public:      
-  // Public methods to work with Stream
+  // Public methods to work with Stream presentation
   
+  /**
+   * Returns the left edge of the stream.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Shape GetLeftShape() const;
+
+  /**
+   * Returns the right edge of the stream.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Shape GetRightShape() const;
+
+  /**
+   * Returns the inlet edge of the stream.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Shape GetInletShape() const;
+
+  /**
+   * Returns the outlet edge of the stream.
+   */
+  HYDRODATA_EXPORT virtual TopoDS_Shape GetOutletShape() const;
+
+
+public:      
+  // Public methods to work with Stream data fields
+
   /**
    * Sets reference hydraulic axis object for stream.
    */
index b701b3af768f9aa793b258a52b8bc1265b5e6bd1..7d3673b44e6a80562876233ae918e9ea7d09f387 100644 (file)
@@ -1,6 +1,34 @@
 
 #include "HYDROData_StreamAltitude.h"
+
 #include "HYDROData_Document.h"
+#include "HYDROData_Profile.h"
+#include "HYDROData_Stream.h"
+#include "HYDROData_ShapesTool.h"
+
+#include <BRep_Tool.hxx>
+
+#include <BRepTopAdaptor_FClass2d.hxx>
+
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+
+#include <Extrema_ExtElC.hxx>
+
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+
+#include <gp_Lin.hxx>
+
+#include <Precision.hxx>
+
+#include <TopExp_Explorer.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Edge.hxx>
+
+#include <TopTools_SequenceOfShape.hxx>
 
 #include <QStringList>
 
@@ -40,10 +68,195 @@ QStringList HYDROData_StreamAltitude::DumpToPython( MapOfTreatedObjects& theTrea
   return aResList;
 }
 
+Standard_Real getAltitudeFromProfile( const Handle(HYDROData_Profile)& theProfile,
+                                      const Standard_Real&             theLeftDist,
+                                      const Standard_Real&             theRightDist )
+{
+  Standard_Real aResAlt = 0.0;
+
+  gp_XY aFirstPoint, aLastPoint;
+  if ( !theProfile->GetLeftPoint( aFirstPoint ) ||
+       !theProfile->GetRightPoint( aLastPoint ) )
+    return aResAlt;
+
+  gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
+  gp_Pnt aPnt2( aLastPoint.X(),  aLastPoint.Y(),  0 );
+
+  Standard_Real aProfileDist = aPnt1.Distance( aPnt2 );
+
+  Standard_Real aCoeff = aProfileDist / ( theLeftDist + theRightDist );
+
+  gp_Pnt anIntPoint( aPnt1.XYZ() + ( aCoeff * theLeftDist ) * gp_Dir( gp_Vec( aPnt1, aPnt2 ) ).XYZ() );
+
+  gp_Lin aPointLine( anIntPoint, gp::DZ() );
+
+  gp_Pnt aPrevPoint;
+  gp_Lin aPrevNormal;
+  HYDROData_Profile::ProfilePoints aProfilePoints = theProfile->GetProfilePoints();
+  for ( int i = 1, n = aProfilePoints.Length(); i <= n; ++i )
+  {
+    gp_Pnt aProfPoint( aProfilePoints.Value( i ) );
+
+    Standard_Real aDist = aPointLine.Distance( aProfPoint );
+    if ( aDist <= gp::Resolution() )
+    {
+      // We found the intersected point
+      aResAlt = aProfPoint.Z();
+      break;
+    }
+   
+    gp_Lin aNormal = aPointLine.Normal( aProfPoint );
+    if ( i == 1 )
+    {
+      aPrevNormal = aNormal;
+      aPrevPoint = aProfPoint;
+      continue;
+    }
+
+    if ( aPrevNormal.Direction().Dot( aNormal.Direction() ) < 0 )
+    {
+      // We found the intersected edge
+      gp_Lin anEdgeLine( aPrevPoint, gp_Dir( gp_Vec( aPrevPoint, aProfPoint ) ) );
+     
+      Extrema_ExtElC anExtrema( aPointLine, anEdgeLine, Precision::Angular() );
+      if ( !anExtrema.IsParallel() )
+      {
+        Extrema_POnCurv aFirstPnt, aSecPnt;
+        anExtrema.Points( 1, aFirstPnt, aSecPnt );
+
+        const gp_Pnt& anIntPnt = aSecPnt.Value();
+        aResAlt = anIntPnt.Z();
+
+        break;
+      }
+    }
+
+    aPrevNormal = aNormal;
+    aPrevPoint = aProfPoint;
+  }
+
+  return aResAlt;
+}
+
+bool HYDROData_StreamAltitude::getBoundaryProfilesForPoint(
+  const gp_XY&               thePoint,
+  Handle(HYDROData_Profile)& theLeftProfile,
+  Handle(HYDROData_Profile)& theRightProfile ) const
+{
+  Handle(HYDROData_Stream) aStream =
+    Handle(HYDROData_Stream)::DownCast( GetFatherObject() );
+  if ( aStream.IsNull() )
+    return false;
+
+  HYDROData_SequenceOfObjects aStreamProfiles = aStream->GetProfiles();
+  if ( aStreamProfiles.Length() < 2 )
+    return false;
+
+  Handle(HYDROData_Profile) aPrevProfile;
+  gp_Pnt aPrevPnt1, aPrevPnt2;
+  for ( int i = 1, n = aStreamProfiles.Length(); i <= n; ++i )
+  {
+    Handle(HYDROData_Profile) aProfile =
+      Handle(HYDROData_Profile)::DownCast( aStreamProfiles.Value( i ) );
+    if ( aProfile.IsNull() )
+      continue;
+
+    gp_XY aFirstPoint, aLastPoint;
+    if ( !aProfile->GetLeftPoint( aFirstPoint ) || !aProfile->GetRightPoint( aLastPoint ) )
+      continue;
+
+    gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
+    gp_Pnt aPnt2( aLastPoint.X(),  aLastPoint.Y(),  0 );
+
+    if ( !aPrevProfile.IsNull() )
+    {
+      BRepBuilderAPI_MakeEdge aLeftMakeEdge( aPrevPnt1, aPrevPnt2 );
+      BRepBuilderAPI_MakeEdge aBotMakeEdge( aPrevPnt2, aPnt2 );
+      BRepBuilderAPI_MakeEdge aRightMakeEdge( aPnt2, aPnt1 );
+      BRepBuilderAPI_MakeEdge aTopMakeEdge( aPnt1, aPrevPnt1 );
+
+      BRepBuilderAPI_MakeWire aMakeWire( aLeftMakeEdge.Edge(), aBotMakeEdge.Edge(), 
+                                         aRightMakeEdge.Edge(), aTopMakeEdge.Edge() );
+
+      BRepBuilderAPI_MakeFace aMakeFace( aMakeWire.Wire() );
+
+      TopoDS_Face aProfilesFace = aMakeFace.Face();
+
+      BRepTopAdaptor_FClass2d aClassifier( aProfilesFace, Precision::Confusion() );
+      TopAbs_State aPointState = aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
+      if ( aPointState != TopAbs_OUT )
+      {
+        theLeftProfile = aPrevProfile;
+        theRightProfile = aProfile;
+        break;
+      }
+    }
+
+    aPrevProfile = aProfile;
+    aPrevPnt1 = aPnt1;
+    aPrevPnt2 = aPnt2;
+  }
+
+  return !theLeftProfile.IsNull() && !theRightProfile.IsNull();
+}
+
 double HYDROData_StreamAltitude::GetAltitudeForPoint( const gp_XY& thePoint ) const
 {
   double aResAltitude = GetInvalidAltitude();
 
+  Handle(HYDROData_Stream) aStream =
+    Handle(HYDROData_Stream)::DownCast( GetFatherObject() );
+  if ( aStream.IsNull() )
+    return aResAltitude;
+
+  TopoDS_Shape aStreamShape = aStream->GetTopShape();
+  if ( aStreamShape.IsNull() )
+    return aResAltitude;
+
+  TopExp_Explorer aStreamFaceExp( aStreamShape, TopAbs_FACE );
+  if ( !aStreamFaceExp.More() )
+    return aResAltitude;
+
+  // Get only face because of 2d profile wires is in compound
+  TopoDS_Face aStreamFace = TopoDS::Face( aStreamFaceExp.Current() );
+
+  // Check if point is inside of stream presentation
+  BRepTopAdaptor_FClass2d aClassifier( aStreamFace, Precision::Confusion() );
+  TopAbs_State aPointState = aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
+  if ( aPointState == TopAbs_OUT )
+    return aResAltitude;
+
+  // Find the two profiles between which the point is lies
+  Handle(HYDROData_Profile) aLeftProfile, aRightProfile;
+  if ( !getBoundaryProfilesForPoint( thePoint, aLeftProfile, aRightProfile ) )
+    return aResAltitude;
+
+  // Find the projections of point to borders of stream
+  gp_XYZ aPointToTest( thePoint.X(), thePoint.Y(), 0.0 );
+
+  TopoDS_Edge aStreamLeftEdge = TopoDS::Edge( aStream->GetLeftShape() );
+  TopoDS_Edge aStreamRightEdge = TopoDS::Edge( aStream->GetRightShape() );
+
+  Standard_Real aFirst = 0.0, aLast = 0.0;
+  Handle(Geom_Curve) anEdgeLeftCurve = BRep_Tool::Curve( aStreamLeftEdge, aFirst, aLast );
+  Handle(Geom_Curve) anEdgeRightCurve = BRep_Tool::Curve( aStreamRightEdge, aFirst, aLast );
+
+  GeomAPI_ProjectPointOnCurve aLeftProject( aPointToTest, anEdgeLeftCurve );
+  GeomAPI_ProjectPointOnCurve aRightProject( aPointToTest, anEdgeRightCurve );
+
+  Standard_Real aLeftDist = aLeftProject.LowerDistance();
+  Standard_Real aRightDist = aRightProject.LowerDistance();
+
+  // Find the altitude in profiles
+  Standard_Real aLeftAlt = getAltitudeFromProfile( aLeftProfile, aLeftDist, aRightDist );
+  Standard_Real aRightAlt = getAltitudeFromProfile( aRightProfile, aLeftDist, aRightDist );
+
+  // Interpolate altitudes
+  Standard_Real aFirstCoeff = aLeftDist / ( aLeftDist + aRightDist );
+  Standard_Real aSecCoeff = aRightDist / ( aLeftDist + aRightDist );
+
+  aResAltitude = aLeftAlt * aFirstCoeff + aRightAlt * aSecCoeff;
+
   return aResAltitude;
 }
 
index 4304545dc0a6d35ca51b3e3d597d36b1eed120e7..2f47af8e51139c6198082cfb4c658060bc4f2aed 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "HYDROData_IAltitudeObject.h"
 
+class Handle(HYDROData_Profile);
 
 DEFINE_STANDARD_HANDLE(HYDROData_StreamAltitude, HYDROData_IAltitudeObject)
 
@@ -51,6 +52,12 @@ public:
    */
   HYDRODATA_EXPORT virtual double           GetAltitudeForPoint( const gp_XY& thePoint ) const;
 
+protected:
+
+  bool getBoundaryProfilesForPoint( const gp_XY&               thePoint,
+                                    Handle(HYDROData_Profile)& theLeftProfile,
+                                    Handle(HYDROData_Profile)& theRightProfile ) const;
+
 protected:
 
   friend class HYDROData_Iterator;