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