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