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