Salome HOME
refs #1340 part.2
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_PolylineOp.cxx
index 745cf67dc6259e75a94b3978857d41d895e8e577..a59af02da79c5366e2075e689443812b797250a9 100755 (executable)
 #include "HYDROGUI_DataObject.h"
 #include "HYDROGUI_PolylineDlg.h"
 #include "HYDROGUI_Tool.h"
+#include "HYDROGUI_Tool2.h"
 #include "HYDROGUI_UpdateFlags.h"
 
 #include <HYDROData_Document.h>
+#include <HYDROData_PolylineOperator.h>
+#include <HYDROData_TopoCurve.h>
 
 #include <CurveCreator_Curve.hxx>
 #include <CurveCreator_Displayer.hxx>
 #include <SUIT_MessageBox.h>
 #include <SUIT_Desktop.h>
 
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Wire.hxx>
+
 //static int ZValueIncrement = 0;
+static const double HYDROGUI_MAXIMAL_DEFLECTION = 1e-2;
 
 HYDROGUI_PolylineOp::HYDROGUI_PolylineOp( HYDROGUI_Module* theModule, bool theIsEdit )
 : HYDROGUI_Operation( theModule ), 
@@ -146,29 +153,95 @@ void HYDROGUI_PolylineOp::startOperation()
     NCollection_Sequence<TCollection_AsciiString>           aSectNames;
     NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
     NCollection_Sequence<bool>                              aSectClosures;
+    bool aIsInCustom = myEditedObject->GetIsInCustomFlag();
+    myEditedObject->SetIsInCustomFlag( true );
     myEditedObject->GetSections( aSectNames, aSectTypes, aSectClosures );
+    myEditedObject->SetIsInCustomFlag( aIsInCustom );
 
-    for ( int i = 1, n = aSectNames.Size(); i <= n; ++i )
+    if (!aSectNames.IsEmpty())
     {
-      QString aSectName = HYDROGUI_Tool::ToQString( aSectNames.Value( i ) );
-      HYDROData_PolylineXY::SectionType aSectType = aSectTypes.Value( i );
-      bool aSectClosure = aSectClosures.Value( i );
+      for ( int i = 1, n = aSectNames.Size(); i <= n; ++i )
+      {
+        QString aSectName = HYDROGUI_Tool::ToQString( aSectNames.Value( i ) );
+        HYDROData_PolylineXY::SectionType aSectType = aSectTypes.Value( i );
+        bool aSectClosure = aSectClosures.Value( i );
+
+        CurveCreator::SectionType aCurveType = CurveCreator::Polyline;
+        if( aSectType == HYDROData_PolylineXY::SECTION_SPLINE )
+          aCurveType = CurveCreator::Spline;
 
-      CurveCreator::SectionType aCurveType = CurveCreator::Polyline;
-      if( aSectType == HYDROData_PolylineXY::SECTION_SPLINE )
-        aCurveType = CurveCreator::Spline;
+        CurveCreator::Coordinates aCurveCoords;
 
-      CurveCreator::Coordinates aCurveCoords;
+        HYDROData_PolylineXY::PointsList aSectPointsList =
+          myEditedObject->GetPoints( i - 1 );
+        for (int k = 1, aNbPoints = aSectPointsList.Size(); k <= aNbPoints; ++k)
+        {
+          const HYDROData_PolylineXY::Point& aSectPoint =
+            aSectPointsList.Value( k );
+          aCurveCoords.push_back( aSectPoint.X() );
+          aCurveCoords.push_back( aSectPoint.Y() );
+        }
 
-      HYDROData_PolylineXY::PointsList aSectPointsList = myEditedObject->GetPoints( i - 1 );
-      for ( int k = 1, aNbPoints = aSectPointsList.Size(); k <= aNbPoints; ++k )
+        myCurve->addSectionInternal( aSectName.toStdString(),
+          aCurveType, aSectClosure, aCurveCoords );
+      }
+    }
+    else
+    {
+      std::deque<CurveCreator::Coordinates> aPs;
+      std::deque<bool> isCloseds;
+      std::vector<TopoDS_Wire> aWires;
+      HYDROData_PolylineOperator::GetWires(myEditedObject, aWires);
+      const int aSCount = aWires.size();
+      bool isError = false;
+      for (int aSI = 0; aSI < aSCount; ++aSI)
       {
-        const HYDROData_PolylineXY::Point& aSectPoint = aSectPointsList.Value( k );
-        aCurveCoords.push_back( aSectPoint.X() );
-        aCurveCoords.push_back( aSectPoint.Y() );
+        HYDROData_TopoCurve aCurve, aCurve2;
+        std::list<gp_XYZ> aPs2;
+        int aMaxPieceCount;
+        if (!aCurve.Initialize(aWires[aSI]) ||
+          (aMaxPieceCount = aCurve.BSplinePiecewiseCurve(
+            HYDROGUI_MAXIMAL_DEFLECTION * 0.1, aCurve2)) == 0)
+        {
+          isError = true;
+          break;
+        }
+
+        double aDefl;
+        aMaxPieceCount *= 100;
+        int aPieceCount = 0;
+        while (aPieceCount < aMaxPieceCount &&
+          (aDefl = HYDROData_PolylineOperator::ReduceDeflection(
+              HYDROGUI_MAXIMAL_DEFLECTION, aCurve2, aPieceCount)) >
+            HYDROGUI_MAXIMAL_DEFLECTION);
+        if (aDefl < 0 || !aCurve2.ValuesInKnots(aPs2))
+        {
+          isError = true;
+          break;
+        }
+
+        aPs.push_back(CurveCreator::Coordinates());
+        CurveCreator::Coordinates& aPs3 = aPs.back();
+        std::list<gp_XYZ>::const_iterator aLastPIt = aPs2.end();
+        std::list<gp_XYZ>::const_iterator aPIt = aPs2.begin();
+        for (; aPIt != aLastPIt; ++aPIt)
+        {
+          const gp_XYZ aP = *aPIt;
+          aPs3.push_back(aP.X());
+          aPs3.push_back(aP.Y());
+        }
+        isCloseds.push_back(aCurve.IsClosed());
       }
 
-      myCurve->addSectionInternal( aSectName.toStdString(), aCurveType, aSectClosure, aCurveCoords );
+      if (!isError)
+      {
+        const TCollection_AsciiString aNamePrefix = "Section_";
+        for (int aSI = 0; aSI < aSCount; ++aSI)
+        {
+          myCurve->addSectionInternal((aNamePrefix + (aSI + 1)).ToCString(),
+            CurveCreator::Spline, isCloseds[aSI], aPs[aSI]);
+        }
+      }
     }
 
     aPolylineName = myEditedObject->GetName();
@@ -280,8 +353,8 @@ bool HYDROGUI_PolylineOp::processApply( int& theUpdateFlags,
 
     aPolylineObj->AddSection( aSectName, aSectType, aSectClosure );
 
-    // Add the points fro section
-    CurveCreator::Coordinates aCurveCoords = myCurve->getPoints( i );
+    // Add the points from section
+    CurveCreator::Coordinates aCurveCoords = myCurve->getCoords( i );
 
     if ( aCurveCoords.size() <= 2 )
     {