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