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