Salome HOME
Bug #61: title of group box create/edit section group box is always "Add element".
[modules/hydro.git] / src / HYDROCurveCreator / CurveCreator_Curve.cxx
1 // Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File:        CurveCreator_Curve.cxx
21 // Author:      Sergey KHROMOV
22
23 #include "CurveCreator_Curve.hxx"
24
25 #include "CurveCreator.hxx"
26 #include "CurveCreator_PosPoint.hxx"
27 #include "CurveCreator_Section.hxx"
28 #include "CurveCreator_Displayer.h"
29 #include "CurveCreator_Utils.h"
30
31 #include <AIS_Shape.hxx>
32 #include <AIS_InteractiveObject.hxx>
33 #include <Geom_CartesianPoint.hxx>
34 #include <gp_Pnt.hxx>
35 #include <gp_Lin.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Face.hxx>
38 #include <TopoDS_Wire.hxx>
39
40 #include <stdio.h>
41
42 //=======================================================================
43 // function: Constructor
44 // purpose:
45 //=======================================================================
46 CurveCreator_Curve::CurveCreator_Curve( const CurveCreator::Dimension theDimension )
47 : myIsLocked  (false),
48   myDimension (theDimension),
49   myDisplayer (NULL),
50   myAISShape  (NULL),
51   myNbUndos   (0),
52   myNbRedos   (0),
53   myUndoDepth (-1),
54   myOpLevel(0),
55   mySkipSorting(false)
56 {
57 }
58
59 //=======================================================================
60 // function: Destructor
61 // purpose:
62 //=======================================================================
63 CurveCreator_Curve::~CurveCreator_Curve()
64 {
65   // Delete all allocated data.
66   clear();
67 }
68
69 //=======================================================================
70 // function: getDimension
71 // purpose:
72 //=======================================================================
73 CurveCreator::Dimension CurveCreator_Curve::getDimension() const
74 {
75   return myDimension;
76 }
77
78 //=======================================================================
79 // function: getUniqSectionName
80 // purpose: return unique section name
81 //=======================================================================
82 std::string CurveCreator_Curve::getUniqSectionName() const
83 {
84     for( int i = 0 ; i < 1000000 ; i++ ){
85         char aBuffer[255];
86         sprintf( aBuffer, "Section_%d", i+1 );
87         std::string aName(aBuffer);
88         int j;
89         for( j = 0 ; j < mySections.size() ; j++ ){
90             if( mySections[j]->myName == aName )
91               break;
92         }
93         if( j == mySections.size() )
94             return aName;
95     }
96     return "";
97 }
98
99 //=======================================================================
100 // function: setDisplayer
101 // purpose: set curve changes Displayer
102 //=======================================================================
103 void CurveCreator_Curve::setDisplayer( CurveCreator_Displayer* theDisplayer )
104 {
105   myDisplayer = theDisplayer;
106 }
107
108 //=======================================================================
109 // function: getDisplayer
110 // purpose: get curve changes Displayer
111 //=======================================================================
112 CurveCreator_Displayer* CurveCreator_Curve::getDisplayer()
113 {
114   return myDisplayer;
115 }
116
117 //=======================================================================
118 // function: removeDisplayer
119 // purpose: remove the attached Displayer
120 //=======================================================================
121 void CurveCreator_Curve::removeDisplayer()
122 {
123   myDisplayer = NULL;
124 }
125
126 //=======================================================================
127 // function: addDiff
128 // purpose:
129 //=======================================================================
130 bool CurveCreator_Curve::addEmptyDiff()
131 {
132   bool isEnabled = false;
133
134   if (myUndoDepth != 0) {
135     // Forget all Redos after the current one.
136     if (myNbRedos > 0) {
137       myNbRedos = 0;
138       myListDiffs.erase(myCurrenPos, myListDiffs.end());
139     }
140
141     if (myUndoDepth == -1 || myNbUndos < myUndoDepth) {
142       // Increase the number of undos.
143       myNbUndos++;
144     } else {
145       // If there are too many differences, remove the first one.
146       myListDiffs.pop_front();
147     }
148
149     // Add new difference.
150     myListDiffs.push_back(CurveCreator_Diff());
151     myCurrenPos = myListDiffs.end();
152     isEnabled = true;
153   }
154
155   return isEnabled;
156 }
157
158 void CurveCreator_Curve::startOperation()
159 {
160     myOpLevel++;
161 }
162
163 void CurveCreator_Curve::finishOperation()
164 {
165    myOpLevel--;
166 }
167
168 //=======================================================================
169 // function: toICoord
170 // purpose:
171 //=======================================================================
172 int CurveCreator_Curve::toICoord(const int theIPnt) const
173 {
174   return theIPnt * myDimension;
175 }
176
177 //=======================================================================
178 // function: setUndoDepth
179 // purpose:
180 //=======================================================================
181 void CurveCreator_Curve::setUndoDepth(const int theDepth)
182 {
183   if (theDepth == 0) {
184     // Reset all undo/redo data.
185     myNbUndos = 0;
186     myNbRedos = 0;
187     myListDiffs.clear();
188     myCurrenPos = myListDiffs.end();
189     myUndoDepth = 0;
190   } else if (theDepth == -1) {
191     // There is nothing to do as the depth become unlimited.
192     myUndoDepth = -1;
193   } else if (theDepth > 0) {
194     // The new "real" depth is set.
195     if (theDepth < myNbRedos) {
196       // The new depth is less then number of redos. Remove the latest redos.
197       int aShift = (myNbRedos - theDepth);
198       ListDiff::iterator aFromPos = myListDiffs.end();
199
200       while (aShift--) {
201         aFromPos--;
202       }
203
204       myListDiffs.erase(aFromPos, myListDiffs.end());
205       myNbRedos = theDepth;
206     }
207
208     if (theDepth < myNbUndos + myNbRedos) {
209       // The new depth is less then the total number of differences.
210       // Remove the first undos.
211       int aShift = (myNbUndos + myNbRedos - theDepth);
212       ListDiff::iterator aToPos = myListDiffs.begin();
213
214       while (aShift--) {
215         aToPos++;
216       }
217
218       myListDiffs.erase(myListDiffs.begin(), aToPos);
219       myNbUndos = theDepth - myNbRedos;
220     }
221
222     myUndoDepth = theDepth;
223   }
224 }
225
226 //=======================================================================
227 // function: getUndoDepth
228 // purpose:
229 //=======================================================================
230 int CurveCreator_Curve::getUndoDepth() const
231 {
232   return myUndoDepth;
233 }
234
235 void CurveCreator_Curve::getCoordinates( int theISection, int theIPoint, double& theX, double& theY, double& theZ ) const
236 {
237   CurveCreator::Coordinates aCoords = getPoint( theISection, theIPoint );
238   theX = aCoords[0];
239   theY = aCoords[1];
240   theZ = 0.;
241   if( getDimension() == CurveCreator::Dim3d ){
242     theZ = aCoords[2];
243   }
244 }
245
246 void CurveCreator_Curve::redisplayCurve()
247 {
248   if( myDisplayer ) {
249     myDisplayer->eraseAll( false );
250     myAISShape = NULL;
251
252     myDisplayer->display( getAISObject( true ), true );
253   }
254 }
255
256 //! For internal use only! Undo/Redo are not used here.
257 bool CurveCreator_Curve::moveSectionInternal(const int theISection,
258                                              const int theNewIndex)
259 {
260   bool res = false;
261   if (theISection != theNewIndex) {
262     CurveCreator_Section *aSection = mySections.at(theISection);
263
264     // Remove section
265     CurveCreator::Sections::iterator anIter = mySections.begin() + theISection;
266
267     mySections.erase(anIter);
268
269     // Insert section.
270     anIter = mySections.begin() + theNewIndex;
271     mySections.insert(anIter, aSection);
272     res = true;
273   }
274   return res;
275 }
276
277 //=======================================================================
278 // function: moveSection
279 // purpose:
280 //=======================================================================
281 bool CurveCreator_Curve::moveSection(const int theISection,
282                                      const int theNewIndex)
283 {
284   bool res = false;
285   // Set the difference.
286   startOperation();
287   if (addEmptyDiff()) {
288     myListDiffs.back().init(this, CurveCreator_Operation::MoveSection,
289                             theISection, theNewIndex);
290   }
291
292   // Update the curve.
293   res = moveSectionInternal(theISection, theNewIndex);
294   finishOperation();
295   return res;
296 }
297
298 /************   Implementation of INTERFACE methods   ************/
299
300 /***********************************************/
301 /***          Undo/Redo methods              ***/
302 /***********************************************/
303
304 //! Get number of available undo operations
305 int CurveCreator_Curve::getNbUndo() const
306 {
307   return myNbUndos;
308 }
309
310 //! Undo previous operation
311 bool CurveCreator_Curve::undo()
312 {
313   bool res = false;
314   if (myNbUndos > 0) {
315     myNbUndos--;
316     myNbRedos++;
317     myCurrenPos--;
318     myCurrenPos->applyUndo(this);
319     res = true;
320   }
321   return res;
322 }
323
324 //! Get number of available redo operations
325 int CurveCreator_Curve::getNbRedo() const
326 {
327   return myNbRedos;
328 }
329
330 //! Redo last previously "undone" operation
331 bool CurveCreator_Curve::redo()
332 {
333   bool res = false;
334   if (myNbRedos > 0) {
335     myCurrenPos->applyRedo(this);
336     myCurrenPos++;
337     myNbRedos--;
338     myNbUndos++;
339     res = true;
340   }
341   return res;
342 }
343
344 /***********************************************/
345 /***           Section methods               ***/
346 /***********************************************/
347 //! For internal use only! Undo/Redo are not used here.
348 bool CurveCreator_Curve::clearInternal()
349 {
350   // erase curve from the viewer
351   if( myDisplayer ) {
352     myDisplayer->eraseAll( true );
353     myAISShape = NULL;
354   }
355   // Delete all allocated data.
356   int i = 0;
357   const int aNbSections = getNbSections();
358
359   for (; i < aNbSections; i++) {
360     delete mySections[i];
361   }
362
363   mySections.clear();
364   
365   return true;
366 }
367
368 //=======================================================================
369 // function: clear
370 // purpose:
371 //=======================================================================
372 bool CurveCreator_Curve::clear()
373 {
374   bool res = false;
375   startOperation();
376   // Set the difference.
377   if (addEmptyDiff()) {
378     myListDiffs.back().init(this, CurveCreator_Operation::Clear);
379   }
380   res = clearInternal();
381   finishOperation();
382   return res;
383 }
384
385 //! For internal use only! Undo/Redo are not used here.
386 bool CurveCreator_Curve::joinInternal( const int theISectionTo, 
387                                        const int theISectionFrom )
388 {
389   bool res = false;
390   CurveCreator_Section *aSection1 = mySections.at(theISectionTo);
391   CurveCreator_Section *aSection2 = mySections.at(theISectionFrom);
392
393   aSection1->myPoints.insert(aSection1->myPoints.end(),
394                              aSection2->myPoints.begin(), 
395                              aSection2->myPoints.end());
396
397   res = removeSection(theISectionFrom);
398   redisplayCurve();
399   return res;
400 }
401
402 //! Join range of sections to one section (join all sections if -1 is passed in theISectionFrom argument)
403 bool CurveCreator_Curve::join( const int theISectionTo, 
404                                const int theISectionFrom )
405 {
406   //TODO
407   bool res = false;
408   if ( theISectionTo != theISectionFrom ) {
409     startOperation();
410     if (addEmptyDiff())
411       myListDiffs.back().init(this, CurveCreator_Operation::Join, theISectionTo, theISectionFrom);
412
413     res = joinInternal( theISectionTo, theISectionFrom );
414
415     finishOperation();
416   }
417   return res;
418 }
419
420 //! Get number of sections
421 int CurveCreator_Curve::getNbSections() const
422 {
423   return mySections.size();
424 }
425
426 //! For internal use only! Undo/Redo are not used here.
427 int CurveCreator_Curve::addSectionInternal
428         (const std::string& theName, const CurveCreator::SectionType theType,
429          const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
430 {
431   CurveCreator_Section *aSection = new CurveCreator_Section;
432
433   std::string aName = theName;
434   if( aName.empty() ){
435       aName = getUniqSectionName();
436   }
437   aSection->myName     = aName;
438   aSection->myType     = theType;
439   aSection->myIsClosed = theIsClosed;
440   aSection->myPoints   = thePoints;
441   mySections.push_back(aSection);
442   redisplayCurve();
443   return mySections.size()-1;
444 }
445
446 //=======================================================================
447 // function: addSection
448 // purpose: adds an empty section
449 //=======================================================================
450 int CurveCreator_Curve::addSection
451         (const std::string& theName, const CurveCreator::SectionType theType,
452          const bool theIsClosed)
453 {
454   int resISection = -1;
455   // Set the difference.
456   startOperation();
457   CurveCreator::Coordinates aCoords; //empty list
458   if (addEmptyDiff()) {
459     myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
460                             theName, aCoords, theType, theIsClosed);
461   }
462
463   resISection = addSectionInternal(theName, theType, theIsClosed, aCoords);
464
465   finishOperation();
466   return resISection;
467 }
468 //=======================================================================
469 // function: addSection
470 // purpose: adds a section with the given points
471 //=======================================================================
472 int CurveCreator_Curve::addSection
473         (const std::string& theName, const CurveCreator::SectionType theType,
474          const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
475 {
476   int resISection = -1;
477   // Set the difference.
478   startOperation();
479   if (addEmptyDiff()) {
480     myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
481                             theName, thePoints, theType, theIsClosed);
482   }
483
484   resISection = addSectionInternal(theName, theType, theIsClosed, thePoints);
485
486   finishOperation();
487   return resISection;
488 }
489
490 //! For internal use only! Undo/Redo are not used here.
491 bool CurveCreator_Curve::removeSectionInternal( const int theISection )
492 {
493   if (theISection == -1) {
494     delete mySections.back();
495     mySections.pop_back();
496   } else {
497     CurveCreator::Sections::iterator anIterRm = mySections.begin() + theISection;
498
499     delete *anIterRm;
500     mySections.erase(anIterRm);
501   }
502   redisplayCurve();
503   return true;
504 }
505   
506 //! Removes the given sections.
507 bool CurveCreator_Curve::removeSection( const int theISection )
508 {
509   bool res = false;
510   // Set the difference.
511   startOperation();
512   if (addEmptyDiff())
513     myListDiffs.back().init(this, CurveCreator_Operation::RemoveSection, theISection);
514
515   res = removeSectionInternal( theISection );
516
517   finishOperation();
518   return res;
519 }
520
521 /**
522  *  Get number of points in specified section or (the total number of points
523  *  in Curve if theISection is equal to -1).
524  */
525 int CurveCreator_Curve::getNbPoints( const int theISection ) const
526 {
527   int aNbCoords = 0;
528
529   if (theISection == -1) {
530     int i = 0;
531     const int aNbSections = getNbSections();
532
533     for (; i < aNbSections; i++) {
534       aNbCoords += mySections[i]->myPoints.size();
535     }
536   } else {
537     if ( ( theISection >= 0 ) && ( theISection < mySections.size() ) )
538       aNbCoords = mySections.at(theISection)->myPoints.size();
539   }
540
541   return aNbCoords/myDimension;
542 }
543
544 void CurveCreator_Curve::setSkipSorting( const bool theIsToSkip )
545 {
546   mySkipSorting = theIsToSkip;
547 }
548
549 bool CurveCreator_Curve::canPointsBeSorted()
550 {
551   return false;
552 }
553
554 //! Get "closed" flag of the specified section
555 bool CurveCreator_Curve::isClosed( const int theISection ) const
556 {
557   return mySections.at(theISection)->myIsClosed;
558 }
559
560 //! For internal use only! Undo/Redo are not used here.
561 bool CurveCreator_Curve::setClosedInternal( const int theISection, 
562                                             const bool theIsClosed )
563 {
564   if (theISection == -1) {
565     int aSize = mySections.size();
566     int i;
567
568     for (i = 0; i < aSize; i++) {
569       mySections[i]->myIsClosed = theIsClosed;
570       redisplayCurve();
571     }
572   } else {
573     mySections.at(theISection)->myIsClosed = theIsClosed;
574     redisplayCurve();
575   }
576   return true;
577 }
578
579 /**
580  *  Set "closed" flag of the specified section (all sections if
581  *  \a theISection is -1).
582  */
583 bool CurveCreator_Curve::setClosed( const int theISection, 
584                                     const bool theIsClosed )
585 {
586   bool res = false;
587   // Set the difference.
588   startOperation();
589   if (addEmptyDiff()) {
590     myListDiffs.back().init(this, CurveCreator_Operation::SetClosed,
591                             theIsClosed, theISection);
592   }
593   res = setClosedInternal( theISection, theIsClosed );
594   finishOperation();
595   return res;
596 }
597
598 //! Returns specified section name
599 std::string CurveCreator_Curve::getSectionName( const int theISection ) const
600 {
601   if( ( theISection >= 0 ) && ( theISection < mySections.size() ))
602     return mySections.at(theISection)->myName;
603   return "";
604 }
605
606 //! For internal use only! Undo/Redo are not used here.
607 bool CurveCreator_Curve::setSectionNameInternal( const int theISection, 
608                                                  const std::string& theName )
609 {
610   bool res = false;
611   if( ( theISection >= 0 ) && ( theISection < mySections.size() )){
612     mySections.at(theISection)->myName = theName;
613     res = true;
614   }
615   return res;
616 }
617
618 /** Set name of the specified section */
619 bool CurveCreator_Curve::setSectionName( const int theISection, 
620                                          const std::string& theName )
621 {
622   bool res = false;
623   // Set the difference.
624   startOperation();
625   if (addEmptyDiff()) {
626     myListDiffs.back().init(this, CurveCreator_Operation::RenameSection,
627                             theName, theISection);
628   }
629   res = setSectionNameInternal( theISection, theName );
630   finishOperation();
631   return res;
632 }
633
634 //! Get type of the specified section
635 CurveCreator::SectionType CurveCreator_Curve::getSectionType
636   ( const int theISection ) const
637 {
638   return mySections.at(theISection)->myType;
639 }
640
641 //! For internal use only! Undo/Redo are not used here.
642 bool CurveCreator_Curve::setSectionTypeInternal( const int theISection, 
643                                                  const CurveCreator::SectionType theType )
644 {
645   if (theISection == -1) {
646     int i = 0;
647     const int aNbSections = getNbSections();
648
649     for (; i < aNbSections; i++) {
650       mySections[i]->myType = theType;
651     }
652     redisplayCurve();
653   } else {
654     if( mySections.at(theISection)->myType != theType ){
655       mySections.at(theISection)->myType = theType;
656       redisplayCurve();
657     }
658   }
659   return true;
660 }
661
662 /**
663  *  Set type of the specified section (or all sections
664  *  if \a theISection is -1).
665  */
666 bool CurveCreator_Curve::setSectionType( const int theISection, 
667                                          const CurveCreator::SectionType theType )
668 {
669   bool res = false;
670   startOperation();
671   // Set the difference.
672   if (addEmptyDiff()) {
673     myListDiffs.back().init(this, CurveCreator_Operation::SetType,
674                             theType, theISection);
675   }
676
677   res = setSectionTypeInternal( theISection, theType );
678
679   finishOperation();
680   return res;
681 }
682
683
684 /***********************************************/
685 /***           Point methods                 ***/
686 /***********************************************/
687
688 //! For internal use only! Undo/Redo are not used here.
689 bool CurveCreator_Curve::addPointsInternal( const CurveCreator::SectionsMap &theSectionsMap )
690 {
691   bool res = false;
692   CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
693   CurveCreator_Section *aSection = 0;
694   for ( ; anIt != theSectionsMap.end(); anIt++ ) {
695     int anISection = anIt->first;
696     aSection = mySections.at(anISection);
697     if( aSection ) {
698       CurveCreator::PosPointsList aSectionPoints = anIt->second;
699       CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
700       for( ; aPntIt != aSectionPoints.end(); aPntIt++ ){
701         int anIPnt = (*aPntIt)->myID;
702         CurveCreator::Coordinates aCoords = (*aPntIt)->myCoords;
703         CurveCreator::Coordinates::iterator anIterPosition;
704         if(anIPnt == -1)
705           anIterPosition = aSection->myPoints.end();
706         else
707           anIterPosition = aSection->myPoints.begin() + toICoord(anIPnt);
708         CurveCreator::Coordinates::const_iterator aFirstPosition = 
709           aCoords.begin();
710         aSection->myPoints.insert(anIterPosition,
711                                   aCoords.begin(), aCoords.end());
712       }
713       res = true;
714     }
715   }
716   if(res)
717     redisplayCurve();
718   return res;
719 }
720
721 /**
722  *  Add one point to the specified section starting from the given theIPnt index
723  *  (or at the end of points if \a theIPnt is -1).
724  */
725 bool CurveCreator_Curve::addPoints( const CurveCreator::Coordinates& theCoords,
726                                     const int theISection,
727                                     const int theIPnt )
728 {
729   bool res = false;
730   CurveCreator::Coordinates aCoords = theCoords;
731   // Set the difference.
732   startOperation();
733   if (addEmptyDiff()) {
734     CurveCreator_ICurve::SectionToPointCoordsList aList;
735     aList.push_back(std::make_pair(std::make_pair(theISection, theIPnt), theCoords));
736     myListDiffs.back().init(this, CurveCreator_Operation::InsertPoints,
737                             aList);
738   }
739   CurveCreator::SectionsMap aSectionsMap;
740   CurveCreator::PosPointsList aPoints;
741   CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( theIPnt, theCoords );
742   aPoints.push_back( aPosPoint );
743   aSectionsMap[theISection] = aPoints;
744
745   res = addPointsInternal( aSectionsMap );
746
747   finishOperation();
748   return res;
749 }
750
751 //! For internal use only! Undo/Redo are not used here.
752 bool CurveCreator_Curve::setPointInternal( const CurveCreator::SectionsMap &theSectionsMap )
753 {
754   bool res = false;
755   // Update the curve.
756   CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
757   CurveCreator_Section *aSection = 0;
758   for ( ; anIt != theSectionsMap.end(); anIt++ ) {
759     int anISection = anIt->first;
760     aSection = mySections.at(anISection);
761     if( aSection ) { 
762       CurveCreator::PosPointsList aSectionPoints = anIt->second;
763       CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
764       for( ; aPntIt != aSectionPoints.end(); aPntIt++ ){
765         int anIPnt = (*aPntIt)->myID;
766         CurveCreator::Coordinates aCoords = (*aPntIt)->myCoords;
767         for ( int i = 0; i < myDimension; i++)
768           aSection->myPoints.at(toICoord(anIPnt) + i) = aCoords[i];
769       }
770       res = true;
771     }
772   }
773   if(res)
774     redisplayCurve();
775   
776   return res;
777 }
778
779 //! Set coordinates of specified point
780 bool CurveCreator_Curve::setPoint( const int theISection,
781                                    const int theIPnt,
782                                    const CurveCreator::Coordinates& theNewCoords )
783 {
784   bool res = false;
785   // Set the difference.
786   startOperation();
787   if (addEmptyDiff()) {
788     CurveCreator_ICurve::SectionToPointCoordsList aList;
789     aList.push_back(std::make_pair(std::make_pair(theISection, theIPnt), theNewCoords));
790     myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
791                             aList);
792   }
793   CurveCreator::SectionsMap aSectionsMap;
794   CurveCreator::PosPointsList aPoints;
795   CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( theIPnt, theNewCoords );
796   aPoints.push_back( aPosPoint );
797   aSectionsMap[theISection] = aPoints;
798
799   int aSize1 = getNbPoints( theISection );
800   res = setPointInternal( aSectionsMap );
801   int aSize2 = getNbPoints( theISection );
802
803   finishOperation();
804
805   return res; 
806 }
807
808 //! Set coordinates of specified points from different sections
809 bool CurveCreator_Curve::setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords)
810 {
811   bool res = false;
812   // Set the difference.
813   startOperation();
814   if (addEmptyDiff()) {
815     myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
816                             theSectionToPntCoords);
817   }
818   CurveCreator::SectionsMap aSectionsMap;
819   CurveCreator::PosPointsList aPosPoints;
820   CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = 
821     theSectionToPntCoords.begin(), aLast = theSectionToPntCoords.end();
822   int aSectionId, aPointId;
823   for ( ; anIt != aLast; anIt++ ) {
824     aPosPoints.clear();
825     aSectionId = anIt->first.first;
826     aPointId = anIt->first.second;
827     CurveCreator::Coordinates aNewCoords = anIt->second;
828     CurveCreator_PosPoint* aPosPoint = 
829       new CurveCreator_PosPoint( aPointId, aNewCoords );
830     if( aSectionsMap.find(aSectionId) != aSectionsMap.end() )
831       aPosPoints = aSectionsMap[aSectionId];
832     aPosPoints.push_back( aPosPoint );
833     aSectionsMap[aSectionId] = aPosPoints;
834     
835   }
836   res = setPointInternal( aSectionsMap );
837   finishOperation();
838
839   return res; 
840 }
841
842 //! For internal use only! Undo/Redo are not used here.
843 bool CurveCreator_Curve::removePointsInternal( const SectionToPointList &thePoints )
844 {
845   bool aRes = false;
846   std::map<int, std::list<int> > aConvPoints;
847   convert( thePoints, aConvPoints );
848   std::map<int, std::list<int> >::const_iterator anIt = aConvPoints.begin(),
849                                           aLast = aConvPoints.end();
850   for ( ; anIt != aLast; anIt++ ) {
851     int aSectionId = anIt->first;
852     aRes = removeSectionPoints(aSectionId, anIt->second);
853   }
854   if( aRes)
855     redisplayCurve();
856
857   return aRes;
858 }
859
860 //! Remove point with given id
861 bool CurveCreator_Curve::removePoint( const int theISection, const int theIPnt )
862 {
863   bool res = false;
864   // Set the difference.
865   startOperation();
866   if (addEmptyDiff()) {
867     myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
868                             theISection, theIPnt);
869   }
870   SectionToPointList aListOfSectionsToPoints;
871   aListOfSectionsToPoints.push_back(std::make_pair(theISection, theIPnt));
872   res = removePointsInternal( aListOfSectionsToPoints );
873   finishOperation();
874   return res;
875 }
876
877 //! Remove several points from different sections with given ids
878 bool CurveCreator_Curve::removeSeveralPoints( const SectionToPointList &theSectionToPntIDs)
879 {
880   bool res = false;
881   // Set the difference.
882   startOperation();
883   if (addEmptyDiff()) {
884     myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
885                             theSectionToPntIDs);
886   }
887   res = removePointsInternal( theSectionToPntIDs );
888   finishOperation();
889   return res;
890 }
891
892   //=======================================================================
893 // function: getCoordinates
894 // purpose:
895 //=======================================================================
896 CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection,
897                                                         const int theIPnt) const
898 {
899   CurveCreator_Section *aSection = mySections.at(theISection);
900   CurveCreator::Coordinates::const_iterator
901     anIter = aSection->myPoints.begin() + toICoord(theIPnt);
902   CurveCreator::Coordinates aResult(anIter, anIter + myDimension);
903
904   return aResult;
905 }
906
907 //=======================================================================
908 // function: getPoints
909 // purpose:
910 //=======================================================================
911 CurveCreator::Coordinates CurveCreator_Curve::getPoints( const int theISection ) const
912 {
913   CurveCreator::Coordinates aCoords;
914   if ( ( theISection >= 0 ) && ( theISection < mySections.size() ) )
915   {
916     aCoords = mySections.at(theISection)->myPoints;
917   }
918   return aCoords;
919 }
920
921 void CurveCreator_Curve::constructAISObject()
922 {
923   TopoDS_Shape aShape;
924   CurveCreator_Utils::constructShape( this, aShape );
925
926   myAISShape = new AIS_Shape( aShape );
927 }
928
929 Handle(AIS_InteractiveObject) CurveCreator_Curve::getAISObject( const bool theNeedToBuild ) const
930 {
931   if ( !myAISShape && theNeedToBuild ) {
932     CurveCreator_Curve* aCurve = (CurveCreator_Curve*)this;
933     aCurve->constructAISObject();
934   }
935   return myAISShape;
936 }
937
938 bool CurveCreator_Curve::removeSectionPoints( const int theSectionId,
939                                               const std::list<int>& thePointIds )
940 {
941   bool aRes = false;
942
943   CurveCreator_Section *aSection = mySections.at( theSectionId );
944   if ( !aSection )
945     return aRes;
946
947   std::list<int> aSectionPoints = thePointIds;
948   aSectionPoints.sort();
949   std::list<int>::const_reverse_iterator aPntIt = aSectionPoints.rbegin();
950   for ( ; aPntIt != aSectionPoints.rend(); aPntIt++ ) {
951     int aPntIndx = *aPntIt;
952     CurveCreator::Coordinates::iterator aFirstPosition;
953     if ( aPntIndx == -1 )
954       aFirstPosition = aSection->myPoints.end() - getDimension();
955     else
956       aFirstPosition = aSection->myPoints.begin() + toICoord( aPntIndx );
957     aSection->myPoints.erase( aFirstPosition, aFirstPosition + getDimension() );
958     aRes = true;
959   }
960   return aRes;
961 }
962
963 void CurveCreator_Curve::convert( const SectionToPointList& thePoints,
964                                   std::map< int, std::list<int> >& theConvPoints )
965 {
966   theConvPoints.clear();
967
968   SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
969   std::list<int> aPoints;
970   int aSectionId, aPointId;
971   for ( ; anIt != aLast; anIt++ ) {
972     aSectionId = anIt->first;
973     aPointId = anIt->second;
974     aPoints.clear();
975     if ( theConvPoints.find( aSectionId ) != theConvPoints.end() )
976       aPoints = theConvPoints[aSectionId];
977     aPoints.push_back( aPointId );
978     theConvPoints[aSectionId] = aPoints;
979   }
980 }