Salome HOME
Remove action should be enabled if the modification mode is activated and there are...
[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 bool HYDROData_PolylineXY::removePoint( const int theISection,
579                                         const int theIPnt )
580 {
581   Handle(TDataStd_RealList) aListX, aListY;
582   getPointsLists( theISection, aListX, aListY, false );
583   if ( aListX.IsNull() || aListY.IsNull() || aListX->IsEmpty() )
584     return false;
585
586   bool anIsOperation = myIsOperation;
587   if ( !anIsOperation )
588     startOperation();
589
590   if ( aListX->Extent() == 1 )
591   {
592     removePointsLists( theISection );
593   }
594   else
595   {
596     TColStd_ListOfReal anOldListX;
597     anOldListX = aListX->List();
598
599     TColStd_ListOfReal anOldListY;
600     anOldListY = aListY->List();
601
602     // Refill the existing lists
603     aListX->Clear();
604     aListY->Clear();
605
606     TColStd_ListIteratorOfListOfReal anIterX( anOldListX );
607     TColStd_ListIteratorOfListOfReal anIterY( anOldListY );
608     for ( int i = 0; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next(), ++i )
609     {
610       if ( i == theIPnt )
611         continue; // skip index to remove
612
613       aListX->Append( anIterX.Value() );
614       aListY->Append( anIterY.Value() );
615     }
616   }
617
618   if ( !anIsOperation )
619     commitOperation();
620
621   return true;
622 }
623
624 CurveCreator::Coordinates HYDROData_PolylineXY::getPoints( const int theISection ) const
625 {
626   CurveCreator::Coordinates aResList;
627
628   if ( theISection < 0 )
629   {
630     int aNbSections = getNbSections();
631     for ( int i = 0; i < aNbSections; ++i )
632     {
633       CurveCreator::Coordinates aSectCoords = getPoints( i );
634       aResList.insert( aResList.end(), aSectCoords.begin(), aSectCoords.end());
635     }
636   }
637   else
638   {
639     Handle(TDataStd_RealList) aListX, aListY;
640     getPointsLists( theISection, aListX, aListY, false );
641     if ( !aListX.IsNull() && !aListY.IsNull() )
642     {
643       TColStd_ListIteratorOfListOfReal anIterX( aListX->List() );
644       TColStd_ListIteratorOfListOfReal anIterY( aListY->List() );
645       for ( ; anIterX.More() && anIterY.More(); anIterX.Next(), anIterY.Next() )
646       {
647         const double& aCoordX = anIterX.Value();
648         const double& aCoordY = anIterY.Value();
649
650         aResList.push_back( aCoordX );
651         aResList.push_back( aCoordY );
652       }
653     }
654   }
655
656   return aResList;
657 }
658
659