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