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