Salome HOME
Bug #487: dump/load script - problem with obstacle.
[modules/hydro.git] / src / HYDROData / HYDROData_StreamAltitude.cxx
index 6692ff0a183c624e9980c85dfba226d81405e78d..8c1f9f69f53bf84c9ef70b73bb9db4dadcb102d5 100644 (file)
@@ -5,11 +5,9 @@
 #include "HYDROData_Profile.h"
 #include "HYDROData_Stream.h"
 #include "HYDROData_ShapesTool.h"
-
+#include <HYDROData_Tool.h>
 #include <BRep_Tool.hxx>
 
-#include <BRepTopAdaptor_FClass2d.hxx>
-
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepBuilderAPI_MakeWire.hxx>
 
 #include <TopTools_SequenceOfShape.hxx>
 
+#include <Geom_Line.hxx>
+
 #include <QStringList>
-#define CLASS2D 1
-#ifdef CLASS2D
-#include <gp_Pln.hxx>
-#include <TopExp.hxx>
-#include <Geom_Plane.hxx>
-#include <BRepBuilderAPI_FindPlane.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TColgp_SequenceOfVec.hxx>
-#include <TopTools_ShapeMapHasher.hxx>
-#undef _NCollection_MapHasher
-#endif
+
 #ifdef DEB_CLASS2D
 #include <BRepTools.hxx>
 #include <BRep_Builder.hxx>
@@ -59,20 +49,6 @@ HYDROData_StreamAltitude::~HYDROData_StreamAltitude()
 {
 }
 
-QStringList HYDROData_StreamAltitude::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
-{
-  QStringList aResList = dumpObjectCreation( theTreatedObjects );
-  QString aName = GetObjPyName();
-
-  // TODO
-
-  aResList << QString( "" );
-  aResList << QString( "%1.Update();" ).arg( aName );
-  aResList << QString( "" );
-
-  return aResList;
-}
-
 Standard_Real getAltitudeFromProfile( const Handle(HYDROData_Profile)& theProfile,
                                       const Standard_Real&             theLeftDist,
                                       const Standard_Real&             theRightDist )
@@ -80,8 +56,8 @@ Standard_Real getAltitudeFromProfile( const Handle(HYDROData_Profile)& theProfil
   Standard_Real aResAlt = 0.0;
 
   gp_XY aFirstPoint, aLastPoint;
-  if ( !theProfile->GetLeftPoint( aFirstPoint ) ||
-       !theProfile->GetRightPoint( aLastPoint ) )
+  if ( !theProfile->GetLeftPoint( aFirstPoint, false ) ||
+       !theProfile->GetRightPoint( aLastPoint, false ) )
     return aResAlt;
 
   gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
@@ -97,7 +73,7 @@ Standard_Real getAltitudeFromProfile( const Handle(HYDROData_Profile)& theProfil
 
   gp_Pnt aPrevPoint;
   gp_Lin aPrevNormal;
-  HYDROData_Profile::ProfilePoints aProfilePoints = theProfile->GetProfilePoints();
+  HYDROData_Profile::ProfilePoints aProfilePoints = theProfile->GetProfilePoints( false );
   for ( int i = 1, n = aProfilePoints.Length(); i <= n; ++i )
   {
     gp_Pnt aProfPoint( aProfilePoints.Value( i ) );
@@ -143,60 +119,6 @@ Standard_Real getAltitudeFromProfile( const Handle(HYDROData_Profile)& theProfil
   return aResAlt;
 }
 
-// =================================== workaround ==============================
-// till fix of Classifier2d bug
-#ifdef CLASS2D
-TopAbs_State ComputePointState(const gp_XY& thePnt2d, const TopoDS_Face& theFace)
-{
-  TopAbs_State aStatus(TopAbs_UNKNOWN);
-  TopoDS_Wire aWire;
-  int nb(0);
-  TopoDS_Iterator it(theFace);
-  for(;it.More();it.Next()) {
-         aWire = TopoDS::Wire(it.Value());
-         nb++;
-  }
-  if(nb > 1 || aWire.IsNull()) return aStatus;
-  gp_Pln aPlane;
-  gp_Vec aNormal;
-  BRepBuilderAPI_FindPlane fndPlane (theFace, Precision::Confusion());
-  if(fndPlane.Found())
-    aPlane = fndPlane.Plane()->Pln();
-  else
-    return aStatus;
-  aNormal = gp_Vec(aPlane.Axis().Direction());
-  if(theFace.Orientation() == TopAbs_REVERSED) 
-    aNormal.Reverse();
-  gp_Pnt aPoint = gp_Pnt (thePnt2d.X(), thePnt2d.Y(), 0);
-  TColgp_SequenceOfVec aSeq;
-  TopTools_MapOfShape aMap;
-  it.Initialize(aWire);
-  for (;it.More(); it.Next()) {
-       const TopoDS_Vertex& aVx = TopExp::FirstVertex(TopoDS::Edge(it.Value()), Standard_True);
-       if(!aMap.Add(aVx))
-         continue;
-       const gp_Pnt& aCurPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVx));
-       if(aPoint.IsEqual(aCurPnt,Precision::Confusion())) {
-      aStatus = TopAbs_ON;
-         return aStatus;
-       }
-       gp_Vec aVec (aPoint, aCurPnt);
-       aSeq.Append(aVec);
-  }
-  Standard_Real anAng(0.0);
-  for(int i = 1;i < aSeq.Length();i++) {
-    const gp_Vec& aV1 = aSeq.Value(i);
-       const gp_Vec& aV2 = aSeq.Value(i+1);
-        anAng += aV1.AngleWithRef(aV2, aNormal);
-  }
-  anAng += aSeq.Value(aSeq.Length()).AngleWithRef(aSeq.Value(1), aNormal);
-  if(abs(anAng) > Precision::Angular())
-    aStatus = TopAbs_IN;
-  else
-        aStatus = TopAbs_OUT;
-  return aStatus;
-}
-#endif
 bool HYDROData_StreamAltitude::getBoundaryProfilesForPoint(
   const gp_XY&               thePoint,
   Handle(HYDROData_Profile)& theLeftProfile,
@@ -221,7 +143,8 @@ bool HYDROData_StreamAltitude::getBoundaryProfilesForPoint(
       continue;
 
     gp_XY aFirstPoint, aLastPoint;
-    if ( !aProfile->GetLeftPoint( aFirstPoint ) || !aProfile->GetRightPoint( aLastPoint ) )
+    if ( !aProfile->GetLeftPoint( aFirstPoint, false ) ||
+         !aProfile->GetRightPoint( aLastPoint, false ) )
       continue;
 
     gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
@@ -249,14 +172,10 @@ bool HYDROData_StreamAltitude::getBoundaryProfilesForPoint(
          BRepBuilderAPI_MakeVertex aMk(aPnt);
          aBB.Add(aCmp, aMk.Vertex());
          BRepTools::Write(aCmp, "ProfileFace.brep");
-#endif
-      BRepTopAdaptor_FClass2d aClassifier( aProfilesFace, Precision::Confusion() );
-         TopAbs_State aPointState = 
-#ifdef CLASS2D
-        ComputePointState(thePoint, aProfilesFace);
-#else
-         aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
-#endif
+#endif     
+
+         TopAbs_State aPointState =  HYDROData_Tool::ComputePointState(thePoint, aProfilesFace);
+
 #ifdef DEB_CLASS2D
          cout << "Point status is = " << aPointState <<endl;
 #endif
@@ -297,13 +216,7 @@ double HYDROData_StreamAltitude::GetAltitudeForPoint( const gp_XY& thePoint ) co
   TopoDS_Face aStreamFace = TopoDS::Face( aStreamFaceExp.Current() );
 
   // Check if point is inside of stream presentation
-  BRepTopAdaptor_FClass2d aClassifier( aStreamFace, Precision::Confusion() );
-  TopAbs_State aPointState = 
-#ifdef CLASS2D
-    ComputePointState(thePoint, aStreamFace);
-#else 
-    aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
-#endif
+  TopAbs_State aPointState = HYDROData_Tool::ComputePointState(thePoint, aStreamFace);
 
 #ifdef DEB_CLASS2D
       cout << "Point status is = " << aPointState <<endl;
@@ -345,10 +258,33 @@ double HYDROData_StreamAltitude::GetAltitudeForPoint( const gp_XY& thePoint ) co
   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;
+  // Left profile line ( the segment between the firts and the last profile point )
+  HYDROData_Profile::ProfilePoints aLeftProfilePoints = aLeftProfile->GetProfilePoints( false );
+  gp_Pnt aLeftProfileP1( aLeftProfilePoints.First() );
+  aLeftProfileP1.SetZ( 0 );
+  gp_Pnt aLeftProfileP2( aLeftProfilePoints.Last() );
+  aLeftProfileP2.SetZ( 0 );
+  gp_Vec aLeftProfileVec( aLeftProfileP1, aLeftProfileP2 );
+  Handle(Geom_Line) aLeftProfileLine = new Geom_Line( gp_Ax1( aLeftProfileP1, aLeftProfileVec ) );
+  // Right profile line
+  HYDROData_Profile::ProfilePoints aRightProfilePoints = aRightProfile->GetProfilePoints( false );
+  gp_Pnt aRightProfileP1( aRightProfilePoints.First() );
+  aRightProfileP1.SetZ( 0 );
+  gp_Pnt aRightProfileP2( aRightProfilePoints.Last() );
+  aRightProfileP2.SetZ( 0 );
+  gp_Vec aRightProfileVec( aRightProfileP1, aRightProfileP2 );
+  Handle(Geom_Line) aRightProfileLine = new Geom_Line( gp_Ax1( aRightProfileP1, aRightProfileVec ) );
+  // The point projections on the left and right profiles
+  GeomAPI_ProjectPointOnCurve aLeftProfileProject( aPointToTest, aLeftProfileLine );
+  GeomAPI_ProjectPointOnCurve aRightProfileProject( aPointToTest, aRightProfileLine );
+  // The point distance to the left and right profiles
+  Standard_Real aLeftProfileDist = aLeftProfileProject.LowerDistance();
+  Standard_Real aRightProfileDist = aRightProfileProject.LowerDistance();
+  // The coefficients
+  Standard_Real aFirstCoeff = aLeftProfileDist / ( aLeftProfileDist + aRightProfileDist );
+  Standard_Real aSecCoeff = aRightProfileDist / ( aLeftProfileDist + aRightProfileDist );
+
+  aResAltitude = aLeftAlt * ( 1 - aFirstCoeff ) + aRightAlt * ( 1 - aSecCoeff );
 
   return aResAltitude;
 }