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