]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_PolylineXY.cxx
Salome HOME
Coloring of objects (Bug #219).
[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     aSectionWiresList.Append( aSectionWire );
236     aMakeWire.Add( aSectionWire );
237   }
238
239   TopoDS_Shape aShape;
240
241   if ( aMakeWire.IsDone() )
242   {
243     aShape = aMakeWire.Shape();
244   }
245   else if ( !aSectionWiresList.IsEmpty() )
246   {
247     // build compound
248     TopoDS_Compound aCompound;
249     
250     BRep_Builder aBuilder;
251     aBuilder.MakeCompound( aCompound );
252     
253     TopTools_ListIteratorOfListOfShape anIter( aSectionWiresList );
254     for ( ; anIter.More(); anIter.Next() )
255     {
256       aBuilder.Add( aCompound, anIter.Value() );
257     }
258     
259     aShape = aCompound;
260   }
261
262   setPolylineShape( aShape );
263 }
264
265 /**
266  * Returns true if polyline is closed
267  */
268 bool HYDROData_PolylineXY::IsClosed() const
269 {
270   NCollection_Sequence<TCollection_AsciiString>           aSectNames;
271   NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
272   NCollection_Sequence<bool>                              aSectClosures;
273   GetSections( aSectNames, aSectTypes, aSectClosures );
274   if( aSectNames.IsEmpty() )
275     return false;
276
277   bool anIsClosed = true;
278   for( int i = 1, n = aSectClosures.Size(); i <= n && anIsClosed; ++i )
279     anIsClosed = anIsClosed && aSectClosures.Value( i );
280
281   return anIsClosed;
282 }
283
284 double HYDROData_PolylineXY::GetDistance( const int theSectionIndex,
285                                           const int thePointIndex ) const
286 {
287   double aResDistance = -1;
288   if ( theSectionIndex < 0 || theSectionIndex >= NbSections() )
289     return aResDistance;
290
291   if ( thePointIndex == 0 )
292     return 0.0;
293
294   SectionType aSectionType = GetSectionType( theSectionIndex );
295   bool anIsSectionClosed = IsClosedSection( theSectionIndex );
296   PointsList aSectPointsList = GetPoints( theSectionIndex );
297   if ( thePointIndex < 0 || thePointIndex >= aSectPointsList.Size()  )
298     return aResDistance;
299
300   if ( aSectionType == SECTION_POLYLINE )
301   {
302     aResDistance = 0.0;
303   
304     Point aPrevPoint = aSectPointsList.Value( 1 );
305     for ( int i = 2, aNbPoints = aSectPointsList.Size(); i <= aNbPoints; ++i )
306     {
307       const Point& aSectPoint = aSectPointsList.Value( i );
308       aResDistance += gp_Pnt2d( aPrevPoint ).Distance( aSectPoint );
309       aPrevPoint = aSectPoint;
310
311       if ( thePointIndex == i - 1 )
312         break;
313     }
314   }
315   else
316   {
317     gp_XYZ aPointToTest;
318
319     int aSectNbPoints = aSectPointsList.Size();
320     NCollection_Sequence<gp_XYZ> aPoints;
321     for( int i = 1 ; i <= aSectNbPoints; ++i )
322     {
323       const Point& aSectPoint = aSectPointsList.Value( i );
324
325       gp_XYZ aPoint( aSectPoint.X(), aSectPoint.Y(), 0.0 );
326       aPoints.Append( aPoint );
327
328       if ( thePointIndex == i - 1 )
329         aPointToTest = aPoint;
330     }
331
332     HYDROData_BSplineOperation aBSpline( aPoints, anIsSectionClosed, LOCAL_SELECTION_TOLERANCE );
333
334     Quantity_Parameter aFirstParam = aBSpline.Curve()->FirstParameter();
335     Quantity_Parameter aSecondParam = aBSpline.Curve()->LastParameter();
336
337     if ( thePointIndex != aSectNbPoints - 1 )
338     {
339       GeomAPI_ProjectPointOnCurve aProject( aPointToTest, aBSpline.Curve() );
340       aSecondParam = aProject.LowerDistanceParameter();
341     }
342
343     GeomAdaptor_Curve anAdap( aBSpline.Curve() );
344     
345     aResDistance = GCPnts_AbscissaPoint::Length( anAdap, aFirstParam, aSecondParam );
346   }
347
348   return aResDistance;
349 }
350
351 int HYDROData_PolylineXY::NbSections() const
352 {
353   Handle(TDataStd_ExtStringList) aNamesList;
354   Handle(TDataStd_IntegerList)   aTypesList;
355   Handle(TDataStd_BooleanList)   aClosuresList;
356   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
357
358   return !aClosuresList.IsNull() ? aClosuresList->Extent() : 0;
359 }
360
361 TCollection_ExtendedString getUniqueSectionName( const Handle(TDataStd_ExtStringList)& theNamesList )
362 {
363   NCollection_Map<TCollection_ExtendedString> aNamesMap;
364
365   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( theNamesList->List() );
366   for ( ; aNamesIter.More(); aNamesIter.Next() )
367     aNamesMap.Add( aNamesIter.Value() );
368
369   TCollection_ExtendedString aResName;
370
371   int aPrefIdx = 1;
372   do
373   {
374     aResName = "Section_" + aPrefIdx;
375     ++aPrefIdx;
376   }
377   while ( aNamesMap.Contains( aResName ) );
378
379   return aResName;
380 }
381
382 void HYDROData_PolylineXY::AddSection( const TCollection_AsciiString& theSectName,
383                                        const SectionType              theSectionType,
384                                        const bool                     theIsClosed )
385 {
386   Handle(TDataStd_ExtStringList) aNamesList;
387   Handle(TDataStd_IntegerList)   aTypesList;
388   Handle(TDataStd_BooleanList)   aClosuresList;
389   getSectionsLists( aNamesList, aTypesList, aClosuresList );
390
391   TCollection_ExtendedString aSectName( theSectName );
392   if ( aSectName.Length() <= 0 )
393     aSectName = getUniqueSectionName( aNamesList );
394
395   aNamesList->Append( aSectName );
396   aTypesList->Append( theSectionType );
397   aClosuresList->Append( theIsClosed );
398
399   SetToUpdate( true );
400 }
401
402 TCollection_AsciiString HYDROData_PolylineXY::GetSectionName( const int theSectionIndex ) const
403 {
404   TCollection_AsciiString aResName;
405
406   Handle(TDataStd_ExtStringList) aNamesList;
407   Handle(TDataStd_IntegerList) aTypesList;
408   Handle(TDataStd_BooleanList) aClosuresList;
409   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
410   if ( aNamesList.IsNull() || theSectionIndex >= aNamesList->Extent() )
411     return aResName;
412
413   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( aNamesList->List() );
414   for ( int i = 0; aNamesIter.More() && i != theSectionIndex; aNamesIter.Next(), ++i );
415
416   if ( aNamesIter.More() )
417     aResName = aNamesIter.Value();
418
419   return aResName;
420 }
421
422 void HYDROData_PolylineXY::SetSectionName( const int                      theSectionIndex, 
423                                            const TCollection_AsciiString& theSectionName )
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;
431
432   TDataStd_ListOfExtendedString anOldNamesList;
433   anOldNamesList = aNamesList->List();
434
435   // Refill the existing list
436   aNamesList->Clear();
437
438   TCollection_ExtendedString aNewSectName = theSectionName;
439
440   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( anOldNamesList );
441   for ( int i = 0; aNamesIter.More(); aNamesIter.Next(), ++i )
442     aNamesList->Append( i == theSectionIndex ? aNewSectName : aNamesIter.Value() );
443
444   SetToUpdate( true );
445 }
446
447 HYDROData_PolylineXY::SectionType HYDROData_PolylineXY::GetSectionType( const int theSectionIndex ) const
448 {
449   Handle(TDataStd_ExtStringList) aNamesList;
450   Handle(TDataStd_IntegerList) aTypesList;
451   Handle(TDataStd_BooleanList) aClosuresList;
452   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
453   if ( aTypesList.IsNull() || theSectionIndex >= aTypesList->Extent() )
454     return SECTION_POLYLINE;
455
456   TColStd_ListIteratorOfListOfInteger aTypesIter( aTypesList->List() );
457   for ( int i = 0; aTypesIter.More() && i != theSectionIndex; aTypesIter.Next(), ++i );
458
459   return aTypesIter.More() ? (SectionType)aTypesIter.Value() : SECTION_POLYLINE;
460 }
461
462 void HYDROData_PolylineXY::SetSectionType( const int         theSectionIndex, 
463                                            const SectionType theSectionType )
464 {
465   Handle(TDataStd_ExtStringList) aNamesList;
466   Handle(TDataStd_IntegerList) aTypesList;
467   Handle(TDataStd_BooleanList) aClosuresList;
468   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
469   if ( aTypesList.IsNull() || theSectionIndex >= aTypesList->Extent() )
470     return;
471
472   TColStd_ListOfInteger anOldTypesList;
473   anOldTypesList = aTypesList->List();
474
475   // Refill the existing list
476   aTypesList->Clear();
477
478   TColStd_ListIteratorOfListOfInteger aTypesIter( anOldTypesList );
479   for ( int i = 0; aTypesIter.More(); aTypesIter.Next(), ++i )
480     aTypesList->Append( i == theSectionIndex ? theSectionType : aTypesIter.Value() );
481
482   SetToUpdate( true );
483 }
484
485 bool HYDROData_PolylineXY::IsClosedSection( const int theSectionIndex ) const
486 {
487   Handle(TDataStd_ExtStringList) aNamesList;
488   Handle(TDataStd_IntegerList) aTypesList;
489   Handle(TDataStd_BooleanList) aClosuresList;
490   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
491   if ( aClosuresList.IsNull() || theSectionIndex >= aClosuresList->Extent() )
492     return false;
493
494   TDataStd_ListIteratorOfListOfByte aClosuresIter( aClosuresList->List() );
495   for ( int i = 0; aClosuresIter.More() && i != theSectionIndex; aClosuresIter.Next(), ++i );
496
497   return aClosuresIter.More() ? (bool)aClosuresIter.Value() : false;
498 }
499
500 void HYDROData_PolylineXY::SetSectionClosed( const int  theSectionIndex, 
501                                              const bool theIsClosed )
502 {
503   Handle(TDataStd_ExtStringList) aNamesList;
504   Handle(TDataStd_IntegerList) aTypesList;
505   Handle(TDataStd_BooleanList) aClosuresList;
506   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
507   if ( aClosuresList.IsNull() || theSectionIndex >= aClosuresList->Extent() )
508     return;
509
510   TDataStd_ListOfByte anOldClosuresList;
511   anOldClosuresList = aClosuresList->List();
512
513   // Refill the existing list
514   aClosuresList->Clear();
515
516   TDataStd_ListIteratorOfListOfByte aClosuresIter( anOldClosuresList );
517   for ( int i = 0; aClosuresIter.More(); aClosuresIter.Next(), ++i )
518     aClosuresList->Append( i == theSectionIndex ? theIsClosed : (bool)aClosuresIter.Value() );
519
520   SetToUpdate( true );
521 }
522
523 void HYDROData_PolylineXY::GetSections( NCollection_Sequence<TCollection_AsciiString>& theSectNames,
524                                         NCollection_Sequence<SectionType>&             theSectTypes,
525                                         NCollection_Sequence<bool>&                    theSectClosures ) const
526 {
527   theSectNames.Clear();
528   theSectTypes.Clear();
529   theSectClosures.Clear();
530
531   Handle(TDataStd_ExtStringList) aNamesList;
532   Handle(TDataStd_IntegerList) aTypesList;
533   Handle(TDataStd_BooleanList) aClosuresList;
534   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
535   if ( aNamesList.IsNull() || aTypesList.IsNull() || aClosuresList.IsNull() )
536     return;
537
538   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( aNamesList->List() );
539   TColStd_ListIteratorOfListOfInteger aTypesIter( aTypesList->List() );
540   TDataStd_ListIteratorOfListOfByte aClosuresIter( aClosuresList->List() );
541   for ( ; aNamesIter.More() && aTypesIter.More() && aClosuresIter.More();
542           aNamesIter.Next(), aTypesIter.Next(), aClosuresIter.Next() )
543   {
544     const TCollection_ExtendedString& aSectName = aNamesIter.Value();
545     SectionType aSectType = (SectionType)aTypesIter.Value();
546     bool aSectClosures = aClosuresIter.Value();
547
548     theSectNames.Append( aSectName );
549     theSectTypes.Append( aSectType );
550     theSectClosures.Append( aSectClosures );
551   }
552 }
553
554 void HYDROData_PolylineXY::RemoveSection( const int theSectionIndex )
555 {
556   Handle(TDataStd_ExtStringList) aNamesList;
557   Handle(TDataStd_IntegerList)   aTypesList;
558   Handle(TDataStd_BooleanList)   aClosuresList;
559   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
560   if ( aNamesList.IsNull() || theSectionIndex >= aNamesList->Extent() )
561     return;
562
563   if ( aNamesList->Extent() == 1 )
564   {
565     removeSectionsLists();
566     removePointsLists();
567   }
568   else
569   {
570     TDataStd_ListOfExtendedString anOldNamesList;
571     anOldNamesList = aNamesList->List();
572
573     TColStd_ListOfInteger anOldTypesList;
574     anOldTypesList = aTypesList->List();
575
576     TDataStd_ListOfByte anOldClosuresList;
577     anOldClosuresList = aClosuresList->List();
578
579     // Refill the existing lists
580     aNamesList->Clear();
581     aTypesList->Clear();
582     aClosuresList->Clear();
583
584     TDataStd_ListIteratorOfListOfExtendedString aNamesIter( anOldNamesList );
585     TColStd_ListIteratorOfListOfInteger aTypesIter( anOldTypesList );
586     TDataStd_ListIteratorOfListOfByte aClosuresIter( anOldClosuresList );
587     for ( int i = 0; aNamesIter.More() && aTypesIter.More() && aClosuresIter.More();
588                      aNamesIter.Next(), aTypesIter.Next(), aClosuresIter.Next(), ++i )
589     {
590       if ( i == theSectionIndex )
591         continue; // skip index to remove
592
593       aNamesList->Append( aNamesIter.Value() );
594       aTypesList->Append( aTypesIter.Value() );
595       aClosuresList->Append( (bool)aClosuresIter.Value() );
596     }
597
598     // Remove points that belongs to removed section
599     removePointsLists( theSectionIndex );
600   }
601
602   SetToUpdate( true );
603 }
604
605 void HYDROData_PolylineXY::RemoveSections()
606 {
607   removeSectionsLists();
608   removePointsLists();
609   SetToUpdate( true );
610 }
611
612 void HYDROData_PolylineXY::AddPoint( const int    theSectionIndex,
613                                      const Point& thePoint,
614                                      const int    thePointIndex )
615 {
616   Handle(TDataStd_RealList) aListX, aListY;
617   getPointsLists( theSectionIndex, aListX, aListY );
618
619   if ( thePointIndex < 0 || thePointIndex >= aListX->Extent() )
620   {
621     aListX->Append( thePoint.X() );
622     aListY->Append( thePoint.Y() );
623   }
624   else
625   {
626     TColStd_ListOfReal anOldListX;
627     anOldListX = aListX->List();
628
629     TColStd_ListOfReal anOldListY;
630     anOldListY = aListY->List();
631
632     // Refill the existing lists
633     aListX->Clear();
634     aListY->Clear();
635
636     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
637     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
638     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
639     {
640       double aCoordX = anIterX.Value();
641       double aCoordY = anIterY.Value();
642
643       if ( i == thePointIndex )
644       {
645         // Insert our new point
646         aListX->Append( thePoint.X() );
647         aListY->Append( thePoint.Y() );
648       }
649
650       aListX->Append( aCoordX );
651       aListY->Append( aCoordY );
652     }
653   }
654
655   SetToUpdate( true );
656 }
657
658 void HYDROData_PolylineXY::SetPoint( const int    theSectionIndex,
659                                      const Point& thePoint,
660                                      const int    thePointIndex )
661 {
662   Handle(TDataStd_RealList) aListX, aListY;
663   getPointsLists( theSectionIndex, aListX, aListY );
664
665   if ( thePointIndex < 0 )
666   {
667     aListX->Prepend( thePoint.X() );
668     aListY->Prepend( thePoint.Y() );
669   }
670   else if ( thePointIndex >= aListX->Extent() )
671   {
672     aListX->Append( thePoint.X() );
673     aListY->Append( thePoint.Y() );
674   }
675   else
676   {
677     TColStd_ListOfReal anOldListX;
678     anOldListX = aListX->List();
679
680     TColStd_ListOfReal anOldListY;
681     anOldListY = aListY->List();
682
683     // Refill the existing lists
684     aListX->Clear();
685     aListY->Clear();
686
687     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
688     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
689     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
690     {
691       double aCoordX = anIterX.Value();
692       double aCoordY = anIterY.Value();
693
694       if ( i == thePointIndex )
695       {
696         // Insert our new point instead of old one
697         aCoordX = thePoint.X();
698         aCoordY = thePoint.Y();
699       }
700
701       aListX->Append( aCoordX );
702       aListY->Append( aCoordY );
703     }
704   }
705
706   SetToUpdate( true );
707 }
708
709 void HYDROData_PolylineXY::RemovePoint( const int theSectionIndex,
710                                         const int thePointIndex )
711 {
712   Handle(TDataStd_RealList) aListX, aListY;
713   getPointsLists( theSectionIndex, aListX, aListY, false );
714   if ( aListX.IsNull() || aListY.IsNull() || aListX->IsEmpty() )
715     return;
716
717   if ( aListX->Extent() == 1 )
718   {
719     removePointsLists( theSectionIndex );
720   }
721   else
722   {
723     TColStd_ListOfReal anOldListX;
724     anOldListX = aListX->List();
725
726     TColStd_ListOfReal anOldListY;
727     anOldListY = aListY->List();
728
729     // Refill the existing lists
730     aListX->Clear();
731     aListY->Clear();
732
733     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
734     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
735     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
736     {
737       if ( i == thePointIndex )
738         continue; // skip index to remove
739
740       aListX->Append( anIterX.Value() );
741       aListY->Append( anIterY.Value() );
742     }
743   }
744
745   SetToUpdate( true );
746 }
747
748 HYDROData_PolylineXY::PointsList HYDROData_PolylineXY::GetPoints( const int theSectionIndex ) const
749 {
750   PointsList aResList;
751
752   Handle(TDataStd_RealList) aListX, aListY;
753   getPointsLists( theSectionIndex, aListX, aListY, false );
754   if ( aListX.IsNull() || aListY.IsNull() || aListX->IsEmpty() )
755     return aResList;
756
757   TColStd_ListIteratorOfListOfReal anIterX( aListX->List() );
758   TColStd_ListIteratorOfListOfReal anIterY( aListY->List() );
759   for ( ; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next() )
760   {
761     Point aPoint( anIterX.Value(), anIterY.Value() );
762     aResList.Append( aPoint );
763   }
764
765   return aResList;
766 }
767
768 QPainterPath HYDROData_PolylineXY::GetPainterPath() const
769 {
770   QPainterPath aPath;
771
772   NCollection_Sequence<TCollection_AsciiString>           aSectNames;
773   NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
774   NCollection_Sequence<bool>                              aSectClosures;
775   GetSections( aSectNames, aSectTypes, aSectClosures );
776
777   for ( int aSectionId = 1, aNbSects = aSectNames.Size(); aSectionId <= aNbSects; aSectionId++ )
778   {
779     TCollection_AsciiString aSectName = aSectNames.Value( aSectionId );
780     SectionType aSectionType = aSectTypes.Value( aSectionId );
781     bool anIsSectionClosed = aSectClosures.Value( aSectionId );
782
783     PointsList aSectPointsList = GetPoints( aSectionId - 1 );
784     if ( aSectPointsList.IsEmpty() )
785       continue;
786
787     NCollection_Sequence<gp_XYZ> aPoints;
788     for( int i = 1, n = aSectPointsList.Size(); i <= n; ++i )
789     {
790       const Point& aSectPoint = aSectPointsList.Value( i );
791
792       gp_XYZ aPoint( aSectPoint.X(), aSectPoint.Y(), 0.0 );
793       aPoints.Append( aPoint );
794     }
795
796     BuildPainterPath( aPath, aSectionType, anIsSectionClosed, aPoints );
797   }
798
799   return aPath;
800 }
801
802