Salome HOME
Create goups for stream.
[modules/hydro.git] / src / HYDROData / HYDROData_PolylineXY.cxx
1
2 #include "HYDROData_PolylineXY.h"
3
4 #include "HYDROData_BSplineOperation.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_Tool.h"
7
8 #include <BRep_Builder.hxx>
9 #include <BRepBuilderAPI_MakeEdge.hxx>
10 #include <BRepBuilderAPI_MakeWire.hxx>
11
12 #include <GeomAPI_ProjectPointOnCurve.hxx>
13 #include <GeomAdaptor_Curve.hxx>
14
15 #include <GCPnts_AbscissaPoint.hxx>
16
17 #include <ImageComposer_MetaTypes.h>
18
19 #include <gp_Pnt.hxx>
20 #include <gp_XY.hxx>
21
22 #include <NCollection_Map.hxx>
23
24 #include <TCollection_ExtendedString.hxx>
25
26 #include <TDataStd_ListIteratorOfListOfByte.hxx>
27 #include <TColStd_ListIteratorOfListOfInteger.hxx>
28 #include <TColStd_ListIteratorOfListOfReal.hxx>
29
30 #include <TDataStd_BooleanList.hxx>
31 #include <TDataStd_ExtStringList.hxx>
32 #include <TDataStd_IntegerList.hxx>
33 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
34 #include <TDataStd_RealList.hxx>
35
36 #include <TopoDS_Iterator.hxx>
37 #include <TopTools_ListIteratorOfListOfShape.hxx>
38 #include <TopTools_HSequenceOfShape.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <ShapeAnalysis_FreeBounds.hxx>
41 #include <TopoDS.hxx>
42 #include <QColor>
43 #include <QPainterPath>
44 #include <QVariant>
45
46 #define PYTHON_POLYLINEXY_ID "KIND_POLYLINEXY"
47
48 const double LOCAL_SELECTION_TOLERANCE = 0.0001;
49
50 IMPLEMENT_STANDARD_HANDLE(HYDROData_PolylineXY, HYDROData_IPolyline)
51 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_PolylineXY, HYDROData_IPolyline)
52
53 HYDROData_PolylineXY::HYDROData_PolylineXY()
54 : HYDROData_IPolyline()
55 {
56 }
57
58 HYDROData_PolylineXY::~HYDROData_PolylineXY()
59 {
60 }
61
62 QStringList HYDROData_PolylineXY::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
63 {
64   QStringList aResList;
65
66   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
67   if ( aDocument.IsNull() )
68     return aResList;
69                              
70   QString aDocName = aDocument->GetDocPyName();
71   QString aPolylineName = GetName();
72
73   aResList << QString( "%1 = %2.CreateObject( %3 );" )
74               .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINEXY_ID );
75   aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
76
77   // Set polilyne data
78   NCollection_Sequence<TCollection_AsciiString>           aSectNames;
79   NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
80   NCollection_Sequence<bool>                              aSectClosures;
81   GetSections( aSectNames, aSectTypes, aSectClosures );
82
83   for ( int i = 1, n = aSectNames.Size(); i <= n; ++i )
84   {
85     const TCollection_AsciiString& aSectName = aSectNames.Value( i );
86     const SectionType& aSectType = aSectTypes.Value( i );
87     bool aSectClosure = aSectClosures.Value( i );
88
89     aResList << QString( "%1.AddSection( \"%2\", %3, %4 );" ).arg( aPolylineName )
90                 .arg( aSectName.ToCString() ).arg( aSectType ).arg( aSectClosure );
91
92     HYDROData_PolylineXY::PointsList aSectPointsList = GetPoints( i );
93     for ( int k = 1, aNbPoints = aSectPointsList.Size(); k <= aNbPoints; ++k )
94     {
95       const Point& aSectPoint = aSectPointsList.Value( k );
96
97       aResList << QString( "%1.AddPoint( %2, QPointF( %3, %4 ) );" ).arg( aPolylineName )
98         .arg( i - 1 ).arg( aSectPoint.X() ).arg( aSectPoint.Y() );
99     }
100   }
101
102   return aResList;
103 }
104
105 QVariant HYDROData_PolylineXY::GetDataVariant()
106 {
107   QPainterPath aPath = GetPainterPath();
108
109   QVariant aVarData;
110   aVarData.setValue<QPainterPath>( aPath );
111   
112   return aVarData;
113 }
114
115 QColor HYDROData_PolylineXY::DefaultWireColor()
116 {
117   return QColor( Qt::red );
118 }
119
120 TopoDS_Shape HYDROData_PolylineXY::GetShape()
121 {
122   return getPolylineShape();
123 }
124
125 TopoDS_Wire HYDROData_PolylineXY::BuildWire( const SectionType&                  theType,
126                                              const bool&                         theIsClosed,
127                                              const NCollection_Sequence<gp_XYZ>& thePoints )
128 {
129   BRepBuilderAPI_MakeWire aMakeWire;
130   
131   if( theType == SECTION_POLYLINE )
132   {
133     for( int i = 1, n = thePoints.Size(); i <= n; ++i )
134     {
135       const gp_XYZ& aFirstPoint = thePoints.Value( i );
136
137       gp_XYZ aLastPoint;
138       if ( i == n )
139       {
140         if( theIsClosed )
141           aLastPoint = thePoints.Value( 1 );
142         else
143           break;
144       }
145       else
146       {
147         aLastPoint = thePoints.Value( i + 1 );
148       }
149
150       gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), aFirstPoint.Z() );
151       gp_Pnt aPnt2( aLastPoint.X(), aLastPoint.Y(), aLastPoint.Z() );
152
153       if ( aPnt1.IsEqual( aPnt2, LOCAL_SELECTION_TOLERANCE ) )
154         continue;
155
156       TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge();
157       aMakeWire.Add( anEdge );
158     }
159   }
160   else //if( theType == PolylineSection::SECTION_SPLINE )
161   {
162     HYDROData_BSplineOperation aBSpline( thePoints, theIsClosed, LOCAL_SELECTION_TOLERANCE );
163
164     TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSpline.Curve() ).Edge();
165     aMakeWire.Add( anEdge );
166   }
167
168   TopoDS_Wire aWire;
169   aMakeWire.Build();
170   if ( aMakeWire.IsDone() )
171     aWire = aMakeWire;
172
173   return aWire;
174 }
175
176 void HYDROData_PolylineXY::BuildPainterPath( QPainterPath&                       thePath,
177                                              const SectionType&                  theType,
178                                              const bool&                         theIsClosed,
179                                              const NCollection_Sequence<gp_XYZ>& thePoints )
180 {
181   if ( thePoints.IsEmpty() )
182     return;
183
184   if ( theType == SECTION_POLYLINE )
185   {
186     const gp_XYZ& aFirstPoint = thePoints.Value( 1 );
187     thePath.moveTo( aFirstPoint.X(), aFirstPoint.Y() );
188
189     for( int i = 2, n = thePoints.Size(); i <= n; ++i )
190     {
191       const gp_XYZ& aSectPoint = thePoints.Value( i );
192
193       thePath.lineTo( aSectPoint.X(), aSectPoint.Y() );
194     }
195
196     if( theIsClosed )
197       thePath.closeSubpath();
198   }
199   else
200   {
201     HYDROData_BSplineOperation aBSpline( thePoints, theIsClosed, LOCAL_SELECTION_TOLERANCE );
202     aBSpline.ComputePath( thePath );
203   }
204 }
205
206 void HYDROData_PolylineXY::Update()
207 {
208   HYDROData_IPolyline::Update();
209
210   NCollection_Sequence<TCollection_AsciiString>           aSectNames;
211   NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
212   NCollection_Sequence<bool>                              aSectClosures;
213   GetSections( aSectNames, aSectTypes, aSectClosures );
214
215   BRepBuilderAPI_MakeWire aMakeWire;
216
217   TopTools_ListOfShape aSectionWiresList;
218
219   for ( int aSectionId = 1, aNbSects = aSectNames.Size(); aSectionId <= aNbSects; aSectionId++ )
220   {
221     TCollection_AsciiString aSectName = aSectNames.Value( aSectionId );
222     SectionType aSectionType = aSectTypes.Value( aSectionId );
223     bool anIsSectionClosed = aSectClosures.Value( aSectionId );
224
225     PointsList aSectPointsList = GetPoints( aSectionId - 1 );
226     if ( aSectPointsList.IsEmpty() )
227       continue;
228     
229     NCollection_Sequence<gp_XYZ> aPoints;
230     for( int i = 1, n = aSectPointsList.Size(); i <= n; ++i )
231     {
232       const Point& aSectPoint = aSectPointsList.Value( i );
233
234       gp_XYZ aPoint( aSectPoint.X(), aSectPoint.Y(), 0.0 );
235       aPoints.Append( aPoint );
236     }
237
238     TopoDS_Wire aSectionWire = BuildWire( aSectionType, anIsSectionClosed, aPoints );
239     if ( !aSectionWire.IsNull() ) {
240       aSectionWiresList.Append( aSectionWire );
241       aMakeWire.Add( aSectionWire );
242     }
243   }
244 // all input wires in the <aSectionWiresList>
245   Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
246   Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
247   TopTools_ListIteratorOfListOfShape it(aSectionWiresList);
248   for(;it.More();it.Next())
249   {
250           TopExp_Explorer it2(it.Value(), TopAbs_EDGE);
251           for(;it2.More();it2.Next()) 
252             aSeqEdges->Append(it2.Current());
253   }
254    BRep_Builder aBB;
255    TopoDS_Compound aCmp;
256    TopoDS_Shape aResult;
257    aBB.MakeCompound(aCmp);
258    if(aSeqEdges->Length() >1)
259    {
260      ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges,1E-5,Standard_False,aSeqWires);
261
262      if( aSeqWires->Length()==1 )
263        aResult = aSeqWires->Value( 1 );
264      else
265      {
266        for (Standard_Integer i = 1; i <= aSeqWires->Length();i++)
267        {
268          const TopoDS_Shape& aS1 = aSeqWires->Value(i);
269          aBB.Add(aCmp, aS1);
270        }
271        aResult = aCmp;
272      }
273          }
274    else if (aSeqEdges->Length() == 1)
275    {
276            BRepBuilderAPI_MakeWire mkWire (TopoDS::Edge(aSeqEdges->Value(1)));
277            if (mkWire.IsDone())
278        aResult = mkWire.Wire();
279    }
280
281   setPolylineShape( aResult );
282 }
283
284 /**
285  * Returns true if polyline is closed
286  */
287 bool HYDROData_PolylineXY::IsClosed() const
288 {
289   NCollection_Sequence<TCollection_AsciiString>           aSectNames;
290   NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
291   NCollection_Sequence<bool>                              aSectClosures;
292   GetSections( aSectNames, aSectTypes, aSectClosures );
293   if( aSectNames.IsEmpty() )
294     return false;
295
296   bool anIsClosed = true;
297   for( int i = 1, n = aSectClosures.Size(); i <= n && anIsClosed; ++i )
298     anIsClosed = anIsClosed && aSectClosures.Value( i );
299
300   return anIsClosed;
301 }
302
303 double HYDROData_PolylineXY::GetDistance( const int theSectionIndex,
304                                           const int thePointIndex ) const
305 {
306   double aResDistance = -1;
307   if ( theSectionIndex < 0 || theSectionIndex >= NbSections() )
308     return aResDistance;
309
310   if ( thePointIndex == 0 )
311     return 0.0;
312
313   SectionType aSectionType = GetSectionType( theSectionIndex );
314   bool anIsSectionClosed = IsClosedSection( theSectionIndex );
315   PointsList aSectPointsList = GetPoints( theSectionIndex );
316   if ( thePointIndex < 0 || thePointIndex >= aSectPointsList.Size()  )
317     return aResDistance;
318
319   if ( aSectionType == SECTION_POLYLINE )
320   {
321     aResDistance = 0.0;
322   
323     Point aPrevPoint = aSectPointsList.Value( 1 );
324     for ( int i = 2, aNbPoints = aSectPointsList.Size(); i <= aNbPoints; ++i )
325     {
326       const Point& aSectPoint = aSectPointsList.Value( i );
327       aResDistance += gp_Pnt2d( aPrevPoint ).Distance( aSectPoint );
328       aPrevPoint = aSectPoint;
329
330       if ( thePointIndex == i - 1 )
331         break;
332     }
333   }
334   else
335   {
336     gp_XYZ aPointToTest;
337
338     int aSectNbPoints = aSectPointsList.Size();
339     NCollection_Sequence<gp_XYZ> aPoints;
340     for( int i = 1 ; i <= aSectNbPoints; ++i )
341     {
342       const Point& aSectPoint = aSectPointsList.Value( i );
343
344       gp_XYZ aPoint( aSectPoint.X(), aSectPoint.Y(), 0.0 );
345       aPoints.Append( aPoint );
346
347       if ( thePointIndex == i - 1 )
348         aPointToTest = aPoint;
349     }
350
351     HYDROData_BSplineOperation aBSpline( aPoints, anIsSectionClosed, LOCAL_SELECTION_TOLERANCE );
352
353     Quantity_Parameter aFirstParam = aBSpline.Curve()->FirstParameter();
354     Quantity_Parameter aSecondParam = aBSpline.Curve()->LastParameter();
355
356     if ( thePointIndex != aSectNbPoints - 1 )
357     {
358       GeomAPI_ProjectPointOnCurve aProject( aPointToTest, aBSpline.Curve() );
359       aSecondParam = aProject.LowerDistanceParameter();
360     }
361
362     GeomAdaptor_Curve anAdap( aBSpline.Curve() );
363     
364     aResDistance = GCPnts_AbscissaPoint::Length( anAdap, aFirstParam, aSecondParam );
365   }
366
367   return aResDistance;
368 }
369
370 int HYDROData_PolylineXY::NbSections() const
371 {
372   Handle(TDataStd_ExtStringList) aNamesList;
373   Handle(TDataStd_IntegerList)   aTypesList;
374   Handle(TDataStd_BooleanList)   aClosuresList;
375   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
376
377   return !aClosuresList.IsNull() ? aClosuresList->Extent() : 0;
378 }
379
380 TCollection_ExtendedString getUniqueSectionName( const Handle(TDataStd_ExtStringList)& theNamesList )
381 {
382   NCollection_Map<TCollection_ExtendedString> aNamesMap;
383
384   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( theNamesList->List() );
385   for ( ; aNamesIter.More(); aNamesIter.Next() )
386     aNamesMap.Add( aNamesIter.Value() );
387
388   TCollection_ExtendedString aResName;
389
390   int aPrefIdx = 1;
391   do
392   {
393     aResName = "Section_" + aPrefIdx;
394     ++aPrefIdx;
395   }
396   while ( aNamesMap.Contains( aResName ) );
397
398   return aResName;
399 }
400
401 void HYDROData_PolylineXY::AddSection( const TCollection_AsciiString& theSectName,
402                                        const SectionType              theSectionType,
403                                        const bool                     theIsClosed )
404 {
405   Handle(TDataStd_ExtStringList) aNamesList;
406   Handle(TDataStd_IntegerList)   aTypesList;
407   Handle(TDataStd_BooleanList)   aClosuresList;
408   getSectionsLists( aNamesList, aTypesList, aClosuresList );
409
410   TCollection_ExtendedString aSectName( theSectName );
411   if ( aSectName.Length() <= 0 )
412     aSectName = getUniqueSectionName( aNamesList );
413
414   aNamesList->Append( aSectName );
415   aTypesList->Append( theSectionType );
416   aClosuresList->Append( theIsClosed );
417
418   SetToUpdate( true );
419 }
420
421 TCollection_AsciiString HYDROData_PolylineXY::GetSectionName( const int theSectionIndex ) const
422 {
423   TCollection_AsciiString aResName;
424
425   Handle(TDataStd_ExtStringList) aNamesList;
426   Handle(TDataStd_IntegerList) aTypesList;
427   Handle(TDataStd_BooleanList) aClosuresList;
428   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
429   if ( aNamesList.IsNull() || theSectionIndex >= aNamesList->Extent() )
430     return aResName;
431
432   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( aNamesList->List() );
433   for ( int i = 0; aNamesIter.More() && i != theSectionIndex; aNamesIter.Next(), ++i );
434
435   if ( aNamesIter.More() )
436     aResName = aNamesIter.Value();
437
438   return aResName;
439 }
440
441 void HYDROData_PolylineXY::SetSectionName( const int                      theSectionIndex, 
442                                            const TCollection_AsciiString& theSectionName )
443 {
444   Handle(TDataStd_ExtStringList) aNamesList;
445   Handle(TDataStd_IntegerList) aTypesList;
446   Handle(TDataStd_BooleanList) aClosuresList;
447   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
448   if ( aNamesList.IsNull() || theSectionIndex >= aNamesList->Extent() )
449     return;
450
451   TDataStd_ListOfExtendedString anOldNamesList;
452   anOldNamesList = aNamesList->List();
453
454   // Refill the existing list
455   aNamesList->Clear();
456
457   TCollection_ExtendedString aNewSectName = theSectionName;
458
459   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( anOldNamesList );
460   for ( int i = 0; aNamesIter.More(); aNamesIter.Next(), ++i )
461     aNamesList->Append( i == theSectionIndex ? aNewSectName : aNamesIter.Value() );
462
463   SetToUpdate( true );
464 }
465
466 HYDROData_PolylineXY::SectionType HYDROData_PolylineXY::GetSectionType( const int theSectionIndex ) const
467 {
468   Handle(TDataStd_ExtStringList) aNamesList;
469   Handle(TDataStd_IntegerList) aTypesList;
470   Handle(TDataStd_BooleanList) aClosuresList;
471   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
472   if ( aTypesList.IsNull() || theSectionIndex >= aTypesList->Extent() )
473     return SECTION_POLYLINE;
474
475   TColStd_ListIteratorOfListOfInteger aTypesIter( aTypesList->List() );
476   for ( int i = 0; aTypesIter.More() && i != theSectionIndex; aTypesIter.Next(), ++i );
477
478   return aTypesIter.More() ? (SectionType)aTypesIter.Value() : SECTION_POLYLINE;
479 }
480
481 void HYDROData_PolylineXY::SetSectionType( const int         theSectionIndex, 
482                                            const SectionType theSectionType )
483 {
484   Handle(TDataStd_ExtStringList) aNamesList;
485   Handle(TDataStd_IntegerList) aTypesList;
486   Handle(TDataStd_BooleanList) aClosuresList;
487   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
488   if ( aTypesList.IsNull() || theSectionIndex >= aTypesList->Extent() )
489     return;
490
491   TColStd_ListOfInteger anOldTypesList;
492   anOldTypesList = aTypesList->List();
493
494   // Refill the existing list
495   aTypesList->Clear();
496
497   TColStd_ListIteratorOfListOfInteger aTypesIter( anOldTypesList );
498   for ( int i = 0; aTypesIter.More(); aTypesIter.Next(), ++i )
499     aTypesList->Append( i == theSectionIndex ? theSectionType : aTypesIter.Value() );
500
501   SetToUpdate( true );
502 }
503
504 bool HYDROData_PolylineXY::IsClosedSection( const int theSectionIndex ) const
505 {
506   Handle(TDataStd_ExtStringList) aNamesList;
507   Handle(TDataStd_IntegerList) aTypesList;
508   Handle(TDataStd_BooleanList) aClosuresList;
509   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
510   if ( aClosuresList.IsNull() || theSectionIndex >= aClosuresList->Extent() )
511     return false;
512
513   TDataStd_ListIteratorOfListOfByte aClosuresIter( aClosuresList->List() );
514   for ( int i = 0; aClosuresIter.More() && i != theSectionIndex; aClosuresIter.Next(), ++i );
515
516   return aClosuresIter.More() ? (bool)aClosuresIter.Value() : false;
517 }
518
519 void HYDROData_PolylineXY::SetSectionClosed( const int  theSectionIndex, 
520                                              const bool theIsClosed )
521 {
522   Handle(TDataStd_ExtStringList) aNamesList;
523   Handle(TDataStd_IntegerList) aTypesList;
524   Handle(TDataStd_BooleanList) aClosuresList;
525   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
526   if ( aClosuresList.IsNull() || theSectionIndex >= aClosuresList->Extent() )
527     return;
528
529   TDataStd_ListOfByte anOldClosuresList;
530   anOldClosuresList = aClosuresList->List();
531
532   // Refill the existing list
533   aClosuresList->Clear();
534
535   TDataStd_ListIteratorOfListOfByte aClosuresIter( anOldClosuresList );
536   for ( int i = 0; aClosuresIter.More(); aClosuresIter.Next(), ++i )
537     aClosuresList->Append( i == theSectionIndex ? theIsClosed : (bool)aClosuresIter.Value() );
538
539   SetToUpdate( true );
540 }
541
542 void HYDROData_PolylineXY::GetSections( NCollection_Sequence<TCollection_AsciiString>& theSectNames,
543                                         NCollection_Sequence<SectionType>&             theSectTypes,
544                                         NCollection_Sequence<bool>&                    theSectClosures ) const
545 {
546   theSectNames.Clear();
547   theSectTypes.Clear();
548   theSectClosures.Clear();
549
550   Handle(TDataStd_ExtStringList) aNamesList;
551   Handle(TDataStd_IntegerList) aTypesList;
552   Handle(TDataStd_BooleanList) aClosuresList;
553   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
554   if ( aNamesList.IsNull() || aTypesList.IsNull() || aClosuresList.IsNull() )
555     return;
556
557   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( aNamesList->List() );
558   TColStd_ListIteratorOfListOfInteger aTypesIter( aTypesList->List() );
559   TDataStd_ListIteratorOfListOfByte aClosuresIter( aClosuresList->List() );
560   for ( ; aNamesIter.More() && aTypesIter.More() && aClosuresIter.More();
561           aNamesIter.Next(), aTypesIter.Next(), aClosuresIter.Next() )
562   {
563     const TCollection_ExtendedString& aSectName = aNamesIter.Value();
564     SectionType aSectType = (SectionType)aTypesIter.Value();
565     bool aSectClosures = aClosuresIter.Value();
566
567     theSectNames.Append( aSectName );
568     theSectTypes.Append( aSectType );
569     theSectClosures.Append( aSectClosures );
570   }
571 }
572
573 void HYDROData_PolylineXY::RemoveSection( const int theSectionIndex )
574 {
575   Handle(TDataStd_ExtStringList) aNamesList;
576   Handle(TDataStd_IntegerList)   aTypesList;
577   Handle(TDataStd_BooleanList)   aClosuresList;
578   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
579   if ( aNamesList.IsNull() || theSectionIndex >= aNamesList->Extent() )
580     return;
581
582   if ( aNamesList->Extent() == 1 )
583   {
584     removeSectionsLists();
585     removePointsLists();
586   }
587   else
588   {
589     TDataStd_ListOfExtendedString anOldNamesList;
590     anOldNamesList = aNamesList->List();
591
592     TColStd_ListOfInteger anOldTypesList;
593     anOldTypesList = aTypesList->List();
594
595     TDataStd_ListOfByte anOldClosuresList;
596     anOldClosuresList = aClosuresList->List();
597
598     // Refill the existing lists
599     aNamesList->Clear();
600     aTypesList->Clear();
601     aClosuresList->Clear();
602
603     TDataStd_ListIteratorOfListOfExtendedString aNamesIter( anOldNamesList );
604     TColStd_ListIteratorOfListOfInteger aTypesIter( anOldTypesList );
605     TDataStd_ListIteratorOfListOfByte aClosuresIter( anOldClosuresList );
606     for ( int i = 0; aNamesIter.More() && aTypesIter.More() && aClosuresIter.More();
607                      aNamesIter.Next(), aTypesIter.Next(), aClosuresIter.Next(), ++i )
608     {
609       if ( i == theSectionIndex )
610         continue; // skip index to remove
611
612       aNamesList->Append( aNamesIter.Value() );
613       aTypesList->Append( aTypesIter.Value() );
614       aClosuresList->Append( (bool)aClosuresIter.Value() );
615     }
616
617     // Remove points that belongs to removed section
618     removePointsLists( theSectionIndex );
619   }
620
621   SetToUpdate( true );
622 }
623
624 void HYDROData_PolylineXY::RemoveSections()
625 {
626   removeSectionsLists();
627   removePointsLists();
628   SetToUpdate( true );
629 }
630
631 void HYDROData_PolylineXY::AddPoint( const int    theSectionIndex,
632                                      const Point& thePoint,
633                                      const int    thePointIndex )
634 {
635   Handle(TDataStd_RealList) aListX, aListY;
636   getPointsLists( theSectionIndex, aListX, aListY );
637
638   if ( thePointIndex < 0 || thePointIndex >= aListX->Extent() )
639   {
640     aListX->Append( thePoint.X() );
641     aListY->Append( thePoint.Y() );
642   }
643   else
644   {
645     TColStd_ListOfReal anOldListX;
646     anOldListX = aListX->List();
647
648     TColStd_ListOfReal anOldListY;
649     anOldListY = aListY->List();
650
651     // Refill the existing lists
652     aListX->Clear();
653     aListY->Clear();
654
655     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
656     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
657     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
658     {
659       double aCoordX = anIterX.Value();
660       double aCoordY = anIterY.Value();
661
662       if ( i == thePointIndex )
663       {
664         // Insert our new point
665         aListX->Append( thePoint.X() );
666         aListY->Append( thePoint.Y() );
667       }
668
669       aListX->Append( aCoordX );
670       aListY->Append( aCoordY );
671     }
672   }
673
674   SetToUpdate( true );
675 }
676
677 void HYDROData_PolylineXY::SetPoint( const int    theSectionIndex,
678                                      const Point& thePoint,
679                                      const int    thePointIndex )
680 {
681   Handle(TDataStd_RealList) aListX, aListY;
682   getPointsLists( theSectionIndex, aListX, aListY );
683
684   if ( thePointIndex < 0 )
685   {
686     aListX->Prepend( thePoint.X() );
687     aListY->Prepend( thePoint.Y() );
688   }
689   else if ( thePointIndex >= aListX->Extent() )
690   {
691     aListX->Append( thePoint.X() );
692     aListY->Append( thePoint.Y() );
693   }
694   else
695   {
696     TColStd_ListOfReal anOldListX;
697     anOldListX = aListX->List();
698
699     TColStd_ListOfReal anOldListY;
700     anOldListY = aListY->List();
701
702     // Refill the existing lists
703     aListX->Clear();
704     aListY->Clear();
705
706     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
707     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
708     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
709     {
710       double aCoordX = anIterX.Value();
711       double aCoordY = anIterY.Value();
712
713       if ( i == thePointIndex )
714       {
715         // Insert our new point instead of old one
716         aCoordX = thePoint.X();
717         aCoordY = thePoint.Y();
718       }
719
720       aListX->Append( aCoordX );
721       aListY->Append( aCoordY );
722     }
723   }
724
725   SetToUpdate( true );
726 }
727
728 void HYDROData_PolylineXY::RemovePoint( const int theSectionIndex,
729                                         const int thePointIndex )
730 {
731   Handle(TDataStd_RealList) aListX, aListY;
732   getPointsLists( theSectionIndex, aListX, aListY, false );
733   if ( aListX.IsNull() || aListY.IsNull() || aListX->IsEmpty() )
734     return;
735
736   if ( aListX->Extent() == 1 )
737   {
738     removePointsLists( theSectionIndex );
739   }
740   else
741   {
742     TColStd_ListOfReal anOldListX;
743     anOldListX = aListX->List();
744
745     TColStd_ListOfReal anOldListY;
746     anOldListY = aListY->List();
747
748     // Refill the existing lists
749     aListX->Clear();
750     aListY->Clear();
751
752     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
753     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
754     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
755     {
756       if ( i == thePointIndex )
757         continue; // skip index to remove
758
759       aListX->Append( anIterX.Value() );
760       aListY->Append( anIterY.Value() );
761     }
762   }
763
764   SetToUpdate( true );
765 }
766
767 HYDROData_PolylineXY::PointsList HYDROData_PolylineXY::GetPoints( const int theSectionIndex ) const
768 {
769   PointsList aResList;
770
771   Handle(TDataStd_RealList) aListX, aListY;
772   getPointsLists( theSectionIndex, aListX, aListY, false );
773   if ( aListX.IsNull() || aListY.IsNull() || aListX->IsEmpty() )
774     return aResList;
775
776   TColStd_ListIteratorOfListOfReal anIterX( aListX->List() );
777   TColStd_ListIteratorOfListOfReal anIterY( aListY->List() );
778   for ( ; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next() )
779   {
780     Point aPoint( anIterX.Value(), anIterY.Value() );
781     aResList.Append( aPoint );
782   }
783
784   return aResList;
785 }
786
787 QPainterPath HYDROData_PolylineXY::GetPainterPath() const
788 {
789   QPainterPath aPath;
790
791   NCollection_Sequence<TCollection_AsciiString>           aSectNames;
792   NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
793   NCollection_Sequence<bool>                              aSectClosures;
794   GetSections( aSectNames, aSectTypes, aSectClosures );
795
796   for ( int aSectionId = 1, aNbSects = aSectNames.Size(); aSectionId <= aNbSects; aSectionId++ )
797   {
798     TCollection_AsciiString aSectName = aSectNames.Value( aSectionId );
799     SectionType aSectionType = aSectTypes.Value( aSectionId );
800     bool anIsSectionClosed = aSectClosures.Value( aSectionId );
801
802     PointsList aSectPointsList = GetPoints( aSectionId - 1 );
803     if ( aSectPointsList.IsEmpty() )
804       continue;
805
806     NCollection_Sequence<gp_XYZ> aPoints;
807     for( int i = 1, n = aSectPointsList.Size(); i <= n; ++i )
808     {
809       const Point& aSectPoint = aSectPointsList.Value( i );
810
811       gp_XYZ aPoint( aSectPoint.X(), aSectPoint.Y(), 0.0 );
812       aPoints.Append( aPoint );
813     }
814
815     BuildPainterPath( aPath, aSectionType, anIsSectionClosed, aPoints );
816   }
817
818   return aPath;
819 }
820
821