Salome HOME
debug of tests for DTM
[modules/hydro.git] / src / HYDROData / HYDROData_PolylineXY.cxx
index 20629aa0d3505300b9d2ea50f274bb3e98b7982d..fc97524992fc8faa9c0e97234727ab7e7d6fbe6d 100644 (file)
@@ -86,6 +86,7 @@
 #include "HYDRO_trace.hxx"
 #include <BRepTools.hxx>
 #include <sstream>
+#include <cmath>
 
 static const Standard_GUID GUID_IS_UNEDITABLE("e5799736-9030-4051-91a4-2e58321fa153");
 
@@ -237,7 +238,7 @@ bool HYDROData_PolylineXY::ImportFromGeomIOR( const TCollection_AsciiString& the
   if ( aShape.IsNull() )
     return false;
 
-  return ImportShape( aShape, false );
+  return ImportShape( aShape, false, NULL );
 #endif
 }
 
@@ -342,7 +343,8 @@ bool convertEdgesToSections( const TopoDS_Edge&
                              NCollection_Sequence<HYDROData_PolylineXY::PointsList>&  theSectPoints,
                              bool                                                     IsCanBeClosed,
                              bool                                                     IsInterpolationAllowed,
-                             double                                                   theDeflection )
+                             double                                                   theDeflection,
+                             const Handle( HYDROData_PolylineXY )&                    theOldPolyline )
 {
   DEBTRACE("convertEdgesToSections")
   Standard_Real aFirst = 0.0, aLast = 0.0;
@@ -442,22 +444,153 @@ bool convertEdgesToSections( const TopoDS_Edge&
       isNewSection = true;
       aPointsList.Clear();
 
-      BRepAdaptor_Curve anAdaptorCurve( theEdge );
-      GCPnts_QuasiUniformDeflection aDiscrete( anAdaptorCurve, theDeflection );
+      BRepAdaptor_Curve anAdaptorCurve(theEdge);
+      if (theOldPolyline.IsNull()) // --- no previous polyline: build a set of points from scratch for the spline
+        {
+          GCPnts_QuasiUniformDeflection aDiscrete(anAdaptorCurve, theDeflection);
 
-      int aNbPoints = aDiscrete.NbPoints();
+          int aNbPoints = aDiscrete.NbPoints();
 
-      // Decrease the number of imported poles because of last one
-      // pole is the closing point which are the start point
-      if ( anIsEdgeClosed ) aNbPoints--;
+          // Decrease the number of imported poles because of last one
+          // pole is the closing point which are the start point
+          if (anIsEdgeClosed)
+            aNbPoints--;
 
-      for ( int i = 1; i <= aNbPoints; ++i )
-      {
-        const gp_Pnt& aPoint = aDiscrete.Value( i );
+          for (int i = 1; i <= aNbPoints; ++i)
+            {
+              const gp_Pnt& aPoint = aDiscrete.Value(i);
+              HYDROData_PolylineXY::Point aSectPoint(aPoint.X(), aPoint.Y());
+              aPointsList.Append(aSectPoint);
+            }
 
-        HYDROData_PolylineXY::Point aSectPoint( aPoint.X(), aPoint.Y() );
-        aPointsList.Append( aSectPoint );
-      }
+          gp_Pnt endPts[] = {gp_Pnt(aPointsList.First().X(),aPointsList.First().Y(), 0),
+                             gp_Pnt(aPointsList.Last().X(),aPointsList.Last().Y(), 0) };
+          DEBTRACE("curve start: "<< endPts[0].X() << " " << endPts[0].Y());
+          DEBTRACE("curve end: "<< endPts[1].X() << " " << endPts[1].Y());
+        }
+      else // --- split of a previous polyline: try to retrieve old sets of points and add intersection points
+        {
+          const gp_Pnt aEndPs[] = { anAdaptorCurve.Value(anAdaptorCurve.FirstParameter()).XYZ(),
+                                    anAdaptorCurve.Value(anAdaptorCurve.LastParameter()).XYZ() };
+          double midPar = (anAdaptorCurve.LastParameter() + anAdaptorCurve.FirstParameter())/2;
+          gp_Pnt midPnt;
+          anAdaptorCurve.D0(midPar, midPnt);
+          DEBTRACE("curve first point: " << aEndPs[0].X() << " " << aEndPs[0].Y() << " " << aEndPs[0].Z());
+          DEBTRACE("curve last point: " << aEndPs[1].X() << " " << aEndPs[1].Y() << " " << aEndPs[1].Z());
+          DEBTRACE("curve mid point: " << midPnt.X() << " " << midPnt.Y() << " " << midPnt.Z());
+
+          std::vector<TopoDS_Wire> aCurves;
+          HYDROData_PolylineOperator::GetWires(theOldPolyline, aCurves);
+
+          int nbSections = theOldPolyline->NbSections();
+          DEBTRACE("nbSections: "<< nbSections << ", nbCurves: " << aCurves.size() );
+          for (int isec = 0; isec < nbSections; isec++)
+            {
+              DEBTRACE("section: "<< isec);
+              bool isOldSectionclosed = theOldPolyline->IsClosedSection(isec);
+              TopoDS_Wire aWire = aCurves[isec]; // we suppose sections and wires are in the same order
+              TopExp_Explorer anExp(aWire, TopAbs_EDGE);
+              TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current()); // the first is OK: only one normally with splines
+              BRepAdaptor_Curve adaptorOldCurve(anEdge);
+              double pfirst = adaptorOldCurve.FirstParameter();
+              double plast = adaptorOldCurve.LastParameter();
+              DEBTRACE("previous curve first last : "<< pfirst << " " << plast);
+              double p[3] = {-1, -1};
+              double d0= ProjectPointToCurve(aEndPs[0].XYZ(), adaptorOldCurve,p[0]);
+              double d1= ProjectPointToCurve(aEndPs[1].XYZ(), adaptorOldCurve,p[1]);
+              double d2= ProjectPointToCurve(midPnt.XYZ(), adaptorOldCurve, p[2]);
+              DEBTRACE("d0: "<<d0<<" d1: "<<d1<<" d2: "<<d2<<" p0: "<<p[0]<<" p1: "<<p[1]<<" p2: "<<p[2]);
+              if ((d0 < 1.e-3) && (d1 < 1.e-3) && (d2 < 1.e-3)) // we got the good old curve (and the good section)
+                {
+                  double pmin = p[0];
+                  double pmax = p[1];
+                  bool forward = true;
+                  DEBTRACE("isOldSectionclosed: " << isOldSectionclosed);
+                  if (!isOldSectionclosed) // no need to check first and last points on an open curve
+                    {
+                      if (pmin > pmax)
+                        {
+                          pmin = p[1];
+                          pmax = p[0];
+                          forward = false;
+                        }
+                    }
+                  else // old section closed: check if we use first or last points...
+                    {
+                      if((pmin < pmax) && ((abs(pmin - pfirst)> 1.e-3) && (abs(pmax - plast) >1.e-3))) // internal points forward
+                        forward = true;
+                      else if ((pmin > pmax) && ((abs(pmin - plast)> 1.e-3) && (abs(pmax - pfirst) >1.e-3))) // internal points reverse
+                        {
+                          pmin = p[1];
+                          pmax = p[0];
+                          forward = false;
+                        }
+                      else if ((abs(pmin - plast) <1.e-3) && (p[2] < pmax)) // forward, replace pmin par pfirst
+                          pmin = pfirst;
+                      else if ((abs(pmin - plast) <1.e-3) && (p[2] > pmax)) // reverse
+                        {
+                          pmin = p[1];
+                          pmax = p[0];
+                          forward = false;
+                        }
+                      else if ((abs(pmax - pfirst) <1.e-3) && (p[2] < pmin)) // reverse
+                        {
+                          pmin = p[1];
+                          pmax = p[0];
+                          forward = false;
+                        }
+                      else if ((abs(pmax - pfirst) <1.e-3) && (p[2] > pmin)) // forward, replace pmax par plast
+                        pmax = plast;
+                   }
+                  DEBTRACE("forward: "<< forward << " pmin " << pmin <<  " pmax " << pmax);
+                  HYDROData_PolylineXY::Point aFirstPoint, aLastPoint;
+                  if (forward)
+                    {
+                      aFirstPoint = HYDROData_PolylineXY::Point(aEndPs[0].X(), aEndPs[0].Y());
+                      aLastPoint = HYDROData_PolylineXY::Point(aEndPs[1].X(), aEndPs[1].Y());
+                    }
+                  else
+                    {
+                      aFirstPoint = HYDROData_PolylineXY::Point(aEndPs[1].X(), aEndPs[1].Y());
+                      aLastPoint = HYDROData_PolylineXY::Point(aEndPs[0].X(), aEndPs[0].Y());
+                    }
+                  aPointsList.Append(aFirstPoint);
+
+                  HYDROData_PolylineXY::PointsList aSectPoints = theOldPolyline->GetPoints(isec, false);
+                  int nbPoints = aSectPoints.Length();
+                  DEBTRACE("nbPoints " << nbPoints);
+                  if (forward)
+                    for (int i=1; i<=nbPoints; i++)
+                      {
+                        HYDROData_PolylineXY::Point aPoint = aSectPoints.Value(i);
+                        gp_XYZ p(aPoint.X(), aPoint.Y(), 0);
+                        double param =-1;
+                        double d = ProjectPointToCurve(p, adaptorOldCurve, param);
+                        if ((param > pmin) && (param < pmax))
+                          {
+                            DEBTRACE("param: " << param);
+                            aPointsList.Append(aPoint);
+                          }
+                      }
+                  else
+                    for (int i=nbPoints; i>0; i--)
+                      {
+                        HYDROData_PolylineXY::Point aPoint = aSectPoints.Value(i);
+                        gp_XYZ p(aPoint.X(), aPoint.Y(), 0);
+                        double param =-1;
+                        double d = ProjectPointToCurve(p, adaptorOldCurve, param);
+                        if ((param > pmin) && (param < pmax))
+                          {
+                            DEBTRACE("param: " << param);
+                            aPointsList.Append(aPoint);
+                          }
+                      }
+
+                  aPointsList.Append(aLastPoint);
+                }
+
+            }
+        }
     }
 
   if ( aPointsList.IsEmpty() )
@@ -483,6 +616,7 @@ bool convertEdgesToSections( const TopoDS_Edge&
 
 bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape,
                                         bool IsInterpolationAllowed,
+                                        const Handle( HYDROData_PolylineXY )& theOldPolyline,
                                         bool IsClosureAllowed,
                                         double theDeviation )
 {
@@ -490,6 +624,10 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape,
   if ( theShape.IsNull() )
     return false;
 
+  //std::string brepName = this->GetName().toStdString();
+  //brepName += ".brep";
+  //BRepTools::Write( theShape, brepName.c_str() );
+
   RemoveSections();
 
   bool anIsCanBeImported = false;
@@ -505,8 +643,9 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape,
     TopoDS_Edge anEdge = TopoDS::Edge( theShape );
 //    anIsCanBeImported = convertEdgeToSection( anEdge, aSectNames, aSectTypes,
 //      aSectClosures, aSectPoints, true, IsInterpolationAllowed, theDeviation );
-    anIsCanBeImported = convertEdgesToSections( anEdge, aSectNames, aSectTypes,
-      aSectClosures, aSectPoints, IsClosureAllowed, IsInterpolationAllowed, theDeviation );
+    anIsCanBeImported = convertEdgesToSections( anEdge, aSectNames, aSectTypes, aSectClosures,
+                                                aSectPoints, IsClosureAllowed, IsInterpolationAllowed,
+                                                theDeviation, theOldPolyline );
   }
   else if ( theShape.ShapeType() == TopAbs_WIRE )
   {
@@ -518,8 +657,9 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape,
     for ( int i = 1, n = anEdges.Length(); i <= n && anIsCanBeImported; ++i )
     {
       TopoDS_Edge aWireEdge = TopoDS::Edge( anEdges.Value( i ) );
-      anIsCanBeImported = convertEdgesToSections( aWireEdge, aSectNames, aSectTypes,
-        aSectClosures, aSectPoints, IsClosureAllowed, IsInterpolationAllowed, theDeviation );
+      anIsCanBeImported = convertEdgesToSections( aWireEdge, aSectNames, aSectTypes, aSectClosures,
+                                                  aSectPoints, IsClosureAllowed, IsInterpolationAllowed,
+                                                  theDeviation, theOldPolyline );
     }
   }
 
@@ -565,7 +705,7 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape,
   }
 
   setEditable( anIsCanBeImported );
-
+  Update();
   return true;
 }
 
@@ -748,35 +888,99 @@ void HYDROData_PolylineXY::setEditable( const bool theIsEditable )
 /**
  * Returns true if polyline is closed
  */
-bool HYDROData_PolylineXY::IsClosed( const bool theIsSimpleCheck ) const
+bool HYDROData_PolylineXY::IsClosed(const bool theIsSimpleCheck) const
 {
+  //DEBTRACE("IsClosed " << theIsSimpleCheck << " " << GetName());
   bool anIsClosed = false;
 
   TopoDS_Shape aShape = GetShape();
-  if ( aShape.IsNull() )
+  if (aShape.IsNull())
     return anIsClosed;
 
   TopTools_SequenceOfShape aWires;
-  HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_WIRE, aWires );
+  HYDROData_ShapesTool::ExploreShapeToShapes(aShape, TopAbs_WIRE, aWires);
 
   int aNbWires = aWires.Length();
-  if ( theIsSimpleCheck )
-  {
-    anIsClosed = aNbWires > 0;
-    for ( int i = 1; i <= aNbWires && anIsClosed; ++i )
+  if (theIsSimpleCheck)
     {
-      const TopoDS_Shape& aWire = aWires.Value( i );
-      anIsClosed = BRep_Tool::IsClosed( aWire );
+      anIsClosed = aNbWires > 0;
+      for (int i = 1; i <= aNbWires && anIsClosed; ++i)
+        {
+          const TopoDS_Shape& aWire = aWires.Value(i);
+          anIsClosed = BRep_Tool::IsClosed(aWire);
+        }
     }
-  }
   else
-  {
-    anIsClosed = aNbWires == 1 && BRep_Tool::IsClosed( aWires.First() );
-  }
+    {
+      if (aNbWires == 1)
+        anIsClosed = BRep_Tool::IsClosed(aWires.First());
+      else
+        {
+          //DEBTRACE("aNbWires " << aNbWires);
+          Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
+          Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
+          for (int i = 1; i <= aNbWires; ++i)
+            {
+              const TopoDS_Shape& aWire = aWires.Value(i);
+              TopExp_Explorer it2(aWire, TopAbs_EDGE);
+              for (; it2.More(); it2.Next())
+                aSeqEdges->Append(it2.Current());
+            }
+          if (aSeqEdges->Length() > 1)
+            {
+              //DEBTRACE(aSeqEdges->Length());
+              ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges, 1E-5, Standard_False, aSeqWires);
+              if (aSeqWires->Length() == 1)
+                {
+                  //DEBTRACE(aSeqWires->Length());
+                  const TopoDS_Wire& aPolylineWire = TopoDS::Wire(aSeqWires->Value(1));
+                  anIsClosed = BRep_Tool::IsClosed(aPolylineWire);
+                }
+            }
+        }
+    }
 
   return anIsClosed;
 }
 
+int HYDROData_PolylineXY::GetNbConnectedWires(Handle(TopTools_HSequenceOfShape)& aConnectedWires) const
+{
+  TopoDS_Shape aShape = GetShape();
+  if (aShape.IsNull())
+    return 0;
+  int aNbconnectedWires = 0;
+  TopTools_SequenceOfShape aWires;
+  HYDROData_ShapesTool::ExploreShapeToShapes(aShape, TopAbs_WIRE, aWires);
+  int aNbWires = aWires.Length();
+  if (aNbWires == 1)
+    {
+      aNbconnectedWires = aNbWires;
+      aConnectedWires->Append(aWires.First());
+    }
+  else
+    {
+      //DEBTRACE("aNbWires " << aNbWires);
+      Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
+      Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
+      for (int i = 1; i <= aNbWires; ++i)
+        {
+          const TopoDS_Shape& aWire = aWires.Value(i);
+          TopExp_Explorer it2(aWire, TopAbs_EDGE);
+          for (; it2.More(); it2.Next())
+            aSeqEdges->Append(it2.Current());
+        }
+      if (aSeqEdges->Length() > 1)
+        {
+          //DEBTRACE(aSeqEdges->Length());
+          ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges, 1E-5, Standard_False, aSeqWires);
+        }
+      aConnectedWires = aSeqWires;
+      aNbconnectedWires = aConnectedWires->Length();
+      DEBTRACE("aNbconnectedWires " << aNbconnectedWires);
+    }
+return aNbconnectedWires;
+}
+
 double HYDROData_PolylineXY::GetDistance( const int theSectionIndex,
                                           const int thePointIndex ) const
 {
@@ -845,38 +1049,6 @@ double HYDROData_PolylineXY::GetDistance( const int theSectionIndex,
   return aResDistance;
 }
 
-//double HYDROData_PolylineXY::GetMinDistance( const int theSectionIndex,
-//                                             const Point& thePoint ) const
-//{
-//  double aResDistance = -1;
-//  if ( theSectionIndex < 0 || theSectionIndex >= NbSections() )
-//    return aResDistance;
-//
-//  std::vector<TopoDS_Wire> aCurves;
-//  HYDROData_PolylineOperator::GetWires(this, aCurves);
-//  if (aCurves.size() != NbSections())
-//    {
-//      DEBTRACE("nbCurves != nbSections " << aCurves.size() << " " << NbSections());
-//      return aResDistance;
-//    }
-//  TopoDS_Wire aWire = aCurves[theSectionIndex];
-//  TopTools_SequenceOfShape anEdges;
-//  HYDROData_ShapesTool::ExploreShapeToShapes( aWire, TopAbs_EDGE, anEdges );
-//  for ( int i = 1, n = anEdges.Length(); i <= n; ++i )
-//    {
-//      DEBTRACE("i: "<< i);
-//      TopoDS_Edge aWireEdge = TopoDS::Edge( anEdges.Value( i ) );
-//      gp_XYZ aPointz = gp_XYZ(thePoint.X(), thePoint.Y(), 0);
-//      Adaptor3d_Curve theCurve = BRepAdaptor_Curve(aWireEdge);
-//      double theParameter = -1;
-//      double d = ProjectPointToCurve(aPointz, theCurve, theParameter);
-//      if (d<aResDistance) aResDistance = d;
-//      DEBTRACE("d[" << i <<"]=" << d);
-//    }
-//  DEBTRACE("distance section "<<theSectionIndex<<" point="<<aResDistance<<" ("<<thePoint.X()<<", "<< thePoint.Y()<<")");
-//  return aResDistance;
-//}
-
 int HYDROData_PolylineXY::NbSections() const
 {
   Handle(TDataStd_ExtStringList) aNamesList;
@@ -1408,5 +1580,5 @@ void HYDROData_PolylineXY::SetIsInCustomFlag( bool theValue )
 
 void HYDROData_PolylineXY::Interpolate()
 {
-  ImportShape( GetShape(), true );
+  ImportShape( GetShape(), true, NULL );
 }