Salome HOME
Update the names of Regions and Zones if case name changed (Bug #110).
[modules/hydro.git] / src / HYDROData / HYDROData_PolylineXY.cxx
1
2 #include "HYDROData_PolylineXY.h"
3
4 #include "HYDROData_Tool.h"
5
6 #include <NCollection_Map.hxx>
7
8 #include <TCollection_ExtendedString.hxx>
9
10 #include <TDataStd_ListIteratorOfListOfByte.hxx>
11 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
12 #include <TColStd_ListIteratorOfListOfInteger.hxx>
13 #include <TColStd_ListIteratorOfListOfReal.hxx>
14
15 #include <TDataStd_BooleanList.hxx>
16 #include <TDataStd_ExtStringList.hxx>
17 #include <TDataStd_Integer.hxx>
18 #include <TDataStd_IntegerList.hxx>
19 #include <TDataStd_RealList.hxx>
20
21 #include <TopoDS_Wire.hxx>
22
23
24 IMPLEMENT_STANDARD_HANDLE(HYDROData_PolylineXY, HYDROData_IPolyline)
25 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_PolylineXY, HYDROData_IPolyline)
26
27 HYDROData_PolylineXY::HYDROData_PolylineXY()
28 : HYDROData_IPolyline()
29 {
30 }
31
32 HYDROData_PolylineXY::~HYDROData_PolylineXY()
33 {
34 }
35
36 CurveCreator_ICurve::ListAISObjects HYDROData_PolylineXY::constructWire() const
37 {
38   // TODO
39   ListAISObjects aProfileObjects;
40   return aProfileObjects;
41 }
42
43 bool HYDROData_PolylineXY::clear()
44 {
45   bool anIsOperation = myIsOperation;
46   if ( !anIsOperation )
47     startOperation();
48
49   removeSectionsLists();
50   removePointsLists();
51
52   if ( !anIsOperation )
53     commitOperation();
54
55   return true;
56 }
57
58 bool HYDROData_PolylineXY::join( const int theISectionTo, 
59                                  const int theISectionFrom )
60 {
61   Handle(TDataStd_ExtStringList) aNamesList;
62   Handle(TDataStd_IntegerList) aTypesList;
63   Handle(TDataStd_BooleanList) aClosuresList;
64   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
65   if ( aNamesList.IsNull() || aNamesList->Extent() <= 1 )
66     return false;
67   
68   bool anIsOperation = myIsOperation;
69
70   if ( theISectionTo == -1 || theISectionFrom == -1 )
71   {
72     // Join all sections to one
73     if ( !anIsOperation )
74       startOperation();
75
76     TCollection_ExtendedString aSectName = aNamesList->First();
77     CurveCreator::SectionType aSectType = (CurveCreator::SectionType)aTypesList->First();
78     bool anIsClosed = aClosuresList->First();
79
80     aNamesList->Clear();
81     aTypesList->Clear();
82     aClosuresList->Clear();
83     
84     aNamesList->Append( aSectName );
85     aTypesList->Append( aSectType );
86     aClosuresList->Append( anIsClosed );
87
88     CurveCreator::Coordinates anAllPoints = getPoints();
89     removePointsLists();
90
91     addPoints( anAllPoints, 0 );
92   }
93   else
94   {
95     // Join selected range of sections to one
96     if ( theISectionFrom >= theISectionTo )
97       return false;
98
99     if ( !anIsOperation )
100       startOperation();
101
102     TDataStd_ListOfExtendedString anOldNamesList;
103     anOldNamesList = aNamesList->List();
104
105     TColStd_ListOfInteger anOldTypesList;
106     anOldTypesList = aTypesList->List();
107
108     TDataStd_ListOfByte anOldClosuresList;
109     anOldClosuresList = aClosuresList->List();
110
111     // Refill the existing lists
112     aNamesList->Clear();
113     aTypesList->Clear();
114     aClosuresList->Clear();
115
116     Handle(TDataStd_RealList) aJoinListX, aJoinListY;
117
118     TDataStd_ListIteratorOfListOfExtendedString aNamesIter( anOldNamesList );
119     TColStd_ListIteratorOfListOfInteger aTypesIter( anOldTypesList );
120     TDataStd_ListIteratorOfListOfByte aClosuresIter( anOldClosuresList );
121
122     int aNbSect = 0;
123     for ( ; aNamesIter.More() && aTypesIter.More() && aClosuresIter.More();
124             aNamesIter.Next(), aTypesIter.Next(), aClosuresIter.Next(), ++aNbSect )
125     {
126       if ( aNbSect < theISectionFrom || aNbSect > theISectionTo )
127       {
128         aNamesList->Append( aNamesIter.Value() );
129         aTypesList->Append( aTypesIter.Value() );
130         aClosuresList->Append( (bool)aClosuresIter.Value() );
131       }
132       else
133       {
134         if ( aNbSect == theISectionFrom )
135         {
136           aNamesList->Append( aNamesIter.Value() );
137           aTypesList->Append( aTypesIter.Value() );
138           aClosuresList->Append( (bool)aClosuresIter.Value() );
139
140           getPointsLists( aNbSect, aJoinListX, aJoinListY );
141         }
142         else
143         {
144           Handle(TDataStd_RealList) aListX, aListY;
145           getPointsLists( aNbSect, aListX, aListY );
146
147           TColStd_ListIteratorOfListOfReal anIterX( aListX->List() );
148           TColStd_ListIteratorOfListOfReal anIterY( aListY->List() );
149           for ( ; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next() )
150           {
151             aJoinListX->Append( anIterX.Value() );
152             aJoinListY->Append( anIterY.Value() );
153           }
154   
155           removePointsLists( aNbSect );
156         }
157       }
158
159       // Move the list which are after theISectionTo to correct place
160       for ( int i = theISectionTo + 1, j = theISectionFrom + 1; i < aNbSect; ++i, j++ )
161       {
162         CurveCreator::Coordinates aPoints = getPoints( i );
163         removePointsLists( i );
164         addPoints( aPoints, j  );
165       }
166     }
167   }
168
169   if ( !anIsOperation )
170     commitOperation();
171
172   return true;
173 }
174
175 int HYDROData_PolylineXY::getNbSections() const
176 {
177   Handle(TDataStd_ExtStringList) aNamesList;
178   Handle(TDataStd_IntegerList) aTypesList;
179   Handle(TDataStd_BooleanList) aClosuresList;
180   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
181
182   return aNamesList.IsNull() ? 0 : aNamesList->Extent();
183 }
184
185 TCollection_ExtendedString getUniqueSectionName( const Handle(TDataStd_ExtStringList)& theNamesList )
186 {
187   NCollection_Map<TCollection_ExtendedString> aNamesMap;
188
189   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( theNamesList->List() );
190   for ( ; aNamesIter.More(); aNamesIter.Next() )
191     aNamesMap.Add( aNamesIter.Value() );
192
193   TCollection_ExtendedString aResName;
194
195   int aPrefIdx = 1;
196   do
197   {
198     aResName = "Section_" + aPrefIdx;
199     ++aPrefIdx;
200   }
201   while ( aNamesMap.Contains( aResName ) );
202
203   return aResName;
204 }
205
206 int HYDROData_PolylineXY::addSection( const std::string&              theName, 
207                                       const CurveCreator::SectionType theType,
208                                       const bool                      theIsClosed )
209 {
210   bool anIsOperation = myIsOperation;
211   if ( !anIsOperation )
212     startOperation();
213
214   Handle(TDataStd_ExtStringList) aNamesList;
215   Handle(TDataStd_IntegerList) aTypesList;
216   Handle(TDataStd_BooleanList) aClosuresList;
217   getSectionsLists( aNamesList, aTypesList, aClosuresList );
218
219   TCollection_ExtendedString aSectName = theName.c_str();
220   if ( aSectName.Length() <= 0 )
221     aSectName = getUniqueSectionName( aNamesList );
222
223   aNamesList->Append( aSectName );
224   aTypesList->Append( theType );
225   aClosuresList->Append( theIsClosed );
226
227   int aSectId = aNamesList->Extent() - 1;
228
229   // Just to create empty data
230   Handle(TDataStd_RealList) aListX, aListY;
231   getPointsLists( aSectId, aListX, aListY );
232
233   if ( !anIsOperation )
234     commitOperation();
235
236   return aSectId;
237 }
238
239 bool HYDROData_PolylineXY::removeSection( const int theISection )
240 {
241   Handle(TDataStd_ExtStringList) aNamesList;
242   Handle(TDataStd_IntegerList) aTypesList;
243   Handle(TDataStd_BooleanList) aClosuresList;
244   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
245   if ( aNamesList.IsNull() || aNamesList->IsEmpty() )
246     return false;
247
248   bool anIsOperation = myIsOperation;
249   if ( !anIsOperation )
250     startOperation();
251
252   if ( aNamesList->Extent() == 1 )
253   {
254     removeSectionsLists();
255     removePointsLists();
256   }
257   else
258   {
259     TDataStd_ListOfExtendedString anOldNamesList;
260     anOldNamesList = aNamesList->List();
261
262     TColStd_ListOfInteger anOldTypesList;
263     anOldTypesList = aTypesList->List();
264
265     TDataStd_ListOfByte anOldClosuresList;
266     anOldClosuresList = aClosuresList->List();
267
268     // Refill the existing lists
269     aNamesList->Clear();
270     aTypesList->Clear();
271     aClosuresList->Clear();
272
273     TDataStd_ListIteratorOfListOfExtendedString aNamesIter( anOldNamesList );
274     TColStd_ListIteratorOfListOfInteger aTypesIter( anOldTypesList );
275     TDataStd_ListIteratorOfListOfByte aClosuresIter( anOldClosuresList );
276     for ( int i = 0; aNamesIter.More() && aTypesIter.More() && aClosuresIter.More();
277                      aNamesIter.Next(), aTypesIter.Next(), aClosuresIter.Next(), ++i )
278     {
279       if ( i == theISection )
280         continue; // skip index to remove
281
282       aNamesList->Append( aNamesIter.Value() );
283       aTypesList->Append( aTypesIter.Value() );
284       aClosuresList->Append( (bool)aClosuresIter.Value() );
285     }
286
287     // Remove points that belong to removed section
288     removePointsLists( theISection );
289   }
290
291   if ( !anIsOperation )
292     commitOperation();
293
294   return true;
295 }
296
297 bool HYDROData_PolylineXY::isClosed( const int theISection ) const
298 {
299   Handle(TDataStd_ExtStringList) aNamesList;
300   Handle(TDataStd_IntegerList) aTypesList;
301   Handle(TDataStd_BooleanList) aClosuresList;
302   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
303   if ( aNamesList.IsNull() || theISection >= aNamesList->Extent() )
304     return false;
305
306   TDataStd_ListIteratorOfListOfByte aClosuresIter( aClosuresList->List() );
307   for ( int i = 0; aClosuresIter.More() && i != theISection; aClosuresIter.Next(), ++i );
308
309   return aClosuresIter.More() ? (bool)aClosuresIter.Value() : false;
310 }
311
312 bool HYDROData_PolylineXY::setClosed( const int  theISection, 
313                                       const bool theIsClosed )
314 {
315   Handle(TDataStd_ExtStringList) aNamesList;
316   Handle(TDataStd_IntegerList) aTypesList;
317   Handle(TDataStd_BooleanList) aClosuresList;
318   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
319   if ( aNamesList.IsNull() || theISection >= aNamesList->Extent() )
320     return false;
321
322   bool anIsOperation = myIsOperation;
323   if ( !anIsOperation )
324     startOperation();
325
326   TDataStd_ListOfByte anOldClosuresList;
327   anOldClosuresList = aClosuresList->List();
328
329   // Refill the existing list
330   aClosuresList->Clear();
331
332   TDataStd_ListIteratorOfListOfByte aClosuresIter( anOldClosuresList );
333   for ( int i = 0; aClosuresIter.More(); aClosuresIter.Next(), ++i )
334     aClosuresList->Append( i == theISection ? theIsClosed : (bool)aClosuresIter.Value() );
335
336   if ( !anIsOperation )
337     commitOperation();
338
339   return true;
340 }
341
342 std::string HYDROData_PolylineXY::getSectionName( const int theISection ) const
343 {
344   Handle(TDataStd_ExtStringList) aNamesList;
345   Handle(TDataStd_IntegerList) aTypesList;
346   Handle(TDataStd_BooleanList) aClosuresList;
347   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
348   if ( aNamesList.IsNull() || theISection >= aNamesList->Extent() )
349     return "";
350
351   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( aNamesList->List() );
352   for ( int i = 0; aNamesIter.More() && i != theISection; aNamesIter.Next(), ++i );
353
354   TCollection_AsciiString aResName;
355   if ( aNamesIter.More() )
356     aResName = aNamesIter.Value();
357
358   return aResName.ToCString();
359 }
360
361 bool HYDROData_PolylineXY::setSectionName( const int          theISection, 
362                                            const std::string& theName )
363 {
364   Handle(TDataStd_ExtStringList) aNamesList;
365   Handle(TDataStd_IntegerList) aTypesList;
366   Handle(TDataStd_BooleanList) aClosuresList;
367   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
368   if ( aNamesList.IsNull() || theISection >= aNamesList->Extent() )
369     return false;
370
371   bool anIsOperation = myIsOperation;
372   if ( !anIsOperation )
373     startOperation();
374
375   TDataStd_ListOfExtendedString anOldNamesList;
376   anOldNamesList = aNamesList->List();
377
378   // Refill the existing list
379   aNamesList->Clear();
380
381   TDataStd_ListIteratorOfListOfExtendedString aNamesIter( aNamesList->List() );
382   for ( int i = 0; aNamesIter.More(); aNamesIter.Next(), ++i )
383     aNamesList->Append( i == theISection ? theName.c_str() : aNamesIter.Value() );
384
385   if ( !anIsOperation )
386     commitOperation();
387
388   return true;
389 }
390
391 CurveCreator::SectionType HYDROData_PolylineXY::getSectionType( const int theISection ) const
392 {
393   Handle(TDataStd_ExtStringList) aNamesList;
394   Handle(TDataStd_IntegerList) aTypesList;
395   Handle(TDataStd_BooleanList) aClosuresList;
396   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
397   if ( aNamesList.IsNull() || theISection >= aNamesList->Extent() )
398     return CurveCreator::Polyline;
399
400   TColStd_ListIteratorOfListOfInteger aTypesIter( aTypesList->List() );
401   for ( int i = 0; aTypesIter.More() && i != theISection; aTypesIter.Next(), ++i );
402
403   return aTypesIter.More() ? (CurveCreator::SectionType)aTypesIter.Value() : CurveCreator::Polyline;
404 }
405
406 bool HYDROData_PolylineXY::setSectionType( const int                       theISection, 
407                                            const CurveCreator::SectionType theType )
408 {
409   Handle(TDataStd_ExtStringList) aNamesList;
410   Handle(TDataStd_IntegerList) aTypesList;
411   Handle(TDataStd_BooleanList) aClosuresList;
412   getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
413   if ( aNamesList.IsNull() || theISection >= aNamesList->Extent() )
414     return false;
415
416   bool anIsOperation = myIsOperation;
417   if ( !anIsOperation )
418     startOperation();
419
420   TColStd_ListOfInteger anOldTypesList;
421   anOldTypesList = aTypesList->List();
422
423   // Refill the existing list
424   aTypesList->Clear();
425
426   TColStd_ListIteratorOfListOfInteger aTypesIter( anOldTypesList );
427   for ( int i = 0; aTypesIter.More(); aTypesIter.Next(), ++i )
428     aTypesList->Append( i == theISection ? theType : aTypesIter.Value() );
429
430   if ( !anIsOperation )
431     commitOperation();
432
433   return true;
434 }
435
436 void addPointsToLists( const CurveCreator::Coordinates& theCoords,
437                        Handle(TDataStd_RealList)&       theListX,
438                        Handle(TDataStd_RealList)&       theListY,
439                        const bool                       theIsAppend )
440 {
441   CurveCreator::Coordinates::const_iterator aBegIter = theCoords.begin();
442   CurveCreator::Coordinates::const_iterator anEndIter = theCoords.end();
443   while ( aBegIter != anEndIter )
444   {
445     const CurveCreator::TypeCoord& aCoordX = *aBegIter++;
446     if ( aBegIter == anEndIter )
447       break;
448
449     const CurveCreator::TypeCoord& aCoordY = *aBegIter++;
450
451     if ( theIsAppend )
452     {
453       theListX->Append( aCoordX );
454       theListY->Append( aCoordY );
455     }
456     else
457     {
458       theListX->Prepend( aCoordX );
459       theListY->Prepend( aCoordY );
460     }
461   }
462 }
463
464 bool HYDROData_PolylineXY::addPoints( const CurveCreator::Coordinates& theCoords,
465                                       const int                        theISection,
466                                       const int                        theIPnt )
467 {
468   bool anIsOperation = myIsOperation;
469   if ( !anIsOperation )
470     startOperation();
471
472   Handle(TDataStd_RealList) aListX, aListY;
473   getPointsLists( theISection, aListX, aListY );
474
475   if ( theIPnt < 0 || theIPnt >= aListX->Extent() )
476   {
477     addPointsToLists( theCoords, aListX, aListY, true );
478   }
479   else
480   {
481     TColStd_ListOfReal anOldListX;
482     anOldListX = aListX->List();
483
484     TColStd_ListOfReal anOldListY;
485     anOldListY = aListY->List();
486
487     // Refill the existing lists
488     aListX->Clear();
489     aListY->Clear();
490
491     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
492     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
493     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
494     {
495       double aCoordX = anIterX.Value();
496       double aCoordY = anIterY.Value();
497
498       if ( i == theIPnt )
499       {
500         // Insert our new points
501         addPointsToLists( theCoords, aListX, aListY, true );
502       }
503
504       aListX->Append( aCoordX );
505       aListY->Append( aCoordY );
506     }
507   }
508
509   if ( !anIsOperation )
510     commitOperation();
511
512   return true;
513 }
514
515 bool HYDROData_PolylineXY::setPoint( const int                        theISection,
516                                      const int                        theIPnt,
517                                      const CurveCreator::Coordinates& theCoords )
518 {
519   if ( theCoords.size() < 2 )
520     return false;
521
522   bool anIsOperation = myIsOperation;
523   if ( !anIsOperation )
524     startOperation();
525
526   Handle(TDataStd_RealList) aListX, aListY;
527   getPointsLists( theISection, aListX, aListY );
528
529   if ( theIPnt < 0 )
530   {
531     addPointsToLists( theCoords, aListX, aListY, false );
532   }
533   else if ( theIPnt >= aListX->Extent() )
534   {
535     addPointsToLists( theCoords, aListX, aListY, true );
536   }
537   else
538   {
539     CurveCreator::Coordinates::const_iterator aBegIter = theCoords.begin();
540     const CurveCreator::TypeCoord& aNewCoordX = *aBegIter++;
541     const CurveCreator::TypeCoord& aNewCoordY = *aBegIter++;
542
543     TColStd_ListOfReal anOldListX;
544     anOldListX = aListX->List();
545
546     TColStd_ListOfReal anOldListY;
547     anOldListY = aListY->List();
548
549     // Refill the existing lists
550     aListX->Clear();
551     aListY->Clear();
552
553     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
554     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
555     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
556     {
557       double aCoordX = anIterX.Value();
558       double aCoordY = anIterY.Value();
559
560       if ( i == theIPnt )
561       {
562         // Insert our new points instead of old one
563         aCoordX = aNewCoordX;
564         aCoordY = aNewCoordY;
565       }
566
567       aListX->Append( aCoordX );
568       aListY->Append( aCoordY );
569     }
570   }
571
572   if ( !anIsOperation )
573     commitOperation();
574
575   return true;
576 }
577
578 //! Set coordinates of specified points from different sections
579 bool HYDROData_PolylineXY::setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords)
580 {
581   return false;
582 }
583
584 bool HYDROData_PolylineXY::removePoint( const int theISection,
585                                         const int theIPnt )
586 {
587   Handle(TDataStd_RealList) aListX, aListY;
588   getPointsLists( theISection, aListX, aListY, false );
589   if ( aListX.IsNull() || aListY.IsNull() || aListX->IsEmpty() )
590     return false;
591
592   bool anIsOperation = myIsOperation;
593   if ( !anIsOperation )
594     startOperation();
595
596   if ( aListX->Extent() == 1 )
597   {
598     removePointsLists( theISection );
599   }
600   else
601   {
602     TColStd_ListOfReal anOldListX;
603     anOldListX = aListX->List();
604
605     TColStd_ListOfReal anOldListY;
606     anOldListY = aListY->List();
607
608     // Refill the existing lists
609     aListX->Clear();
610     aListY->Clear();
611
612     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
613     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
614     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
615     {
616       if ( i == theIPnt )
617         continue; // skip index to remove
618
619       aListX->Append( anIterX.Value() );
620       aListY->Append( anIterY.Value() );
621     }
622   }
623
624   if ( !anIsOperation )
625     commitOperation();
626
627   return true;
628 }
629
630 //! Remove several points from different sections with given ids
631 bool HYDROData_PolylineXY::removeSeveralPoints( const SectionToPointList &theSectionToPntIDs)
632 {
633   return false;
634 }
635
636 CurveCreator::Coordinates HYDROData_PolylineXY::getPoints( const int theISection ) const
637 {
638   CurveCreator::Coordinates aResList;
639
640   if ( theISection < 0 )
641   {
642     int aNbSections = getNbSections();
643     for ( int i = 0; i < aNbSections; ++i )
644     {
645       CurveCreator::Coordinates aSectCoords = getPoints( i );
646       aResList.insert( aResList.end(), aSectCoords.begin(), aSectCoords.end());
647     }
648   }
649   else
650   {
651     Handle(TDataStd_RealList) aListX, aListY;
652     getPointsLists( theISection, aListX, aListY, false );
653     if ( !aListX.IsNull() && !aListY.IsNull() )
654     {
655       TColStd_ListIteratorOfListOfReal anIterX( aListX->List() );
656       TColStd_ListIteratorOfListOfReal anIterY( aListY->List() );
657       for ( ; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next() )
658       {
659         const double& aCoordX = anIterX.Value();
660         const double& aCoordY = anIterY.Value();
661
662         aResList.push_back( aCoordX );
663         aResList.push_back( aCoordY );
664       }
665     }
666   }
667
668   return aResList;
669 }
670
671