Salome HOME
Fix Undo/Redo of AddSection, RemoveSection, AddPoint, RemovePoint.
[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_Section.hxx"
27 #include "CurveCreator_Displayer.h"
28
29 #include <AIS_Point.hxx>
30 #include <AIS_Line.hxx>
31 #include <AIS_Shape.hxx>
32 #include <BRepBuilderAPI_MakeEdge.hxx>
33 #include <BRepBuilderAPI_MakeWire.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 #include <TColgp_HArray1OfPnt.hxx>
41 #include <GeomAPI_Interpolate.hxx>
42
43 #include <stdio.h>
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 }
59
60 //=======================================================================
61 // function: Destructor
62 // purpose:
63 //=======================================================================
64 CurveCreator_Curve::~CurveCreator_Curve()
65 {
66   // Delete all allocated data.
67   clear();
68 }
69
70 //=======================================================================
71 // function: getDimension
72 // purpose:
73 //=======================================================================
74 CurveCreator::Dimension CurveCreator_Curve::getDimension() const
75 {
76   return myDimension;
77 }
78
79 //=======================================================================
80 // function: getUniqSectionName
81 // purpose: return unique section name
82 //=======================================================================
83 std::string CurveCreator_Curve::getUniqSectionName() const
84 {
85     for( int i = 0 ; i < 1000000 ; i++ ){
86         char aBuffer[255];
87         sprintf( aBuffer, "Section_%d", i+1 );
88         std::string aName(aBuffer);
89         int j;
90         for( j = 0 ; j < mySections.size() ; j++ ){
91             if( mySections[j]->myName == aName )
92               break;
93         }
94         if( j == mySections.size() )
95             return aName;
96     }
97     return "";
98 }
99
100 //=======================================================================
101 // function: setDisplayer
102 // purpose: set curve changes Displayer
103 //=======================================================================
104 void CurveCreator_Curve::setDisplayer( CurveCreator_Displayer* theDisplayer )
105 {
106   myDisplayer = theDisplayer;
107 }
108
109 //=======================================================================
110 // function: removeDisplayer
111 // purpose: remove the attached Displayer
112 //=======================================================================
113 void CurveCreator_Curve::removeDisplayer()
114 {
115   myDisplayer = NULL;
116 }
117
118 //=======================================================================
119 // function: addDiff
120 // purpose:
121 //=======================================================================
122 bool CurveCreator_Curve::addEmptyDiff()
123 {
124   bool isEnabled = false;
125
126   if (myUndoDepth != 0) {
127     // Forget all Redos after the current one.
128     if (myNbRedos > 0) {
129       myNbRedos = 0;
130       myListDiffs.erase(myCurrenPos, myListDiffs.end());
131     }
132
133     if (myUndoDepth == -1 || myNbUndos < myUndoDepth) {
134       // Increase the number of undos.
135       myNbUndos++;
136     } else {
137       // If there are too many differences, remove the first one.
138       myListDiffs.pop_front();
139     }
140
141     // Add new difference.
142     myListDiffs.push_back(CurveCreator_Diff());
143     myCurrenPos = myListDiffs.end();
144     isEnabled = true;
145   }
146
147   return isEnabled;
148 }
149
150 void CurveCreator_Curve::startOperation()
151 {
152     myOpLevel++;
153 }
154
155 void CurveCreator_Curve::finishOperation()
156 {
157    myOpLevel--;
158 }
159
160 //=======================================================================
161 // function: toICoord
162 // purpose:
163 //=======================================================================
164 int CurveCreator_Curve::toICoord(const int theIPnt) const
165 {
166   return theIPnt * myDimension;
167 }
168
169 std::vector<Handle_AIS_InteractiveObject> CurveCreator_Curve::constructSection( int theISection ) const
170 {
171   std::vector<Handle_AIS_InteractiveObject> aSectionRepresentation;
172
173   CurveCreator::SectionType aSectType = getSectionType( theISection );
174   int aSectSize = getNbPoints( theISection );
175   bool aSectIsClosed = isClosed( theISection );
176
177   if( aSectType == CurveCreator::Polyline )
178   {
179     int iPoint = 0; 
180     for( ; iPoint < ( aSectSize - 1 ) ; iPoint++ ){
181       Handle_AIS_Point anAISPnt = getAISPoint(theISection, iPoint);
182       aSectionRepresentation.push_back( anAISPnt );
183       Handle_AIS_Line aLine = getAISLine( theISection, iPoint, iPoint+1 );
184       aSectionRepresentation.push_back( aLine );
185     }
186     if( aSectSize != 0 ){
187       Handle_AIS_Point anAISPnt = getAISPoint(theISection, iPoint); 
188       aSectionRepresentation.push_back( anAISPnt );
189       if( isClosed(theISection) && ( aSectSize > 1 ) ){
190         Handle_AIS_Line aLine = getAISLine( theISection, iPoint, 0 );
191         aSectionRepresentation.push_back( aLine );
192       }
193     }
194   }
195   else if( aSectType == CurveCreator::Spline )
196   {
197     std::vector<double> aPoints;
198     for( int iPoint = 0; iPoint < aSectSize; iPoint++ )
199     {
200       Handle_AIS_Point anAISPnt = getAISPoint( theISection, iPoint );
201       aSectionRepresentation.push_back( anAISPnt );
202
203       CurveCreator::Coordinates aCoords = getPoint( theISection, iPoint );
204       double aX = aCoords[0];
205       double aY = aCoords[1];
206       double aZ = aCoords[2];
207       aPoints.push_back( aX );
208       aPoints.push_back( aY );
209     }
210
211     if( aSectSize > 1 )
212     {
213       Handle(Geom_BSplineCurve) aBSplineCurve;
214       // fill array for algorithm by the received coordinates
215       int aLen = aPoints.size() / 2;
216       Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt (1, aLen);
217       std::vector<double>::const_iterator aListIter = aPoints.begin();
218       for (int ind = 1; ind <= aLen; ind++) {
219         gp_Pnt aPnt(gp::Origin());
220         aPnt.SetX(*aListIter);
221         aListIter++;
222         aPnt.SetY(*aListIter);
223         aListIter++;
224         aPnt.SetZ(0);
225         aHCurvePoints->SetValue(ind, aPnt);
226       }
227       // compute BSpline
228       GeomAPI_Interpolate aGBC(aHCurvePoints, aSectIsClosed, gp::Resolution());
229       aGBC.Perform();
230       if (aGBC.IsDone()) {
231         aBSplineCurve = aGBC.Curve();
232       }
233       TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSplineCurve ).Edge();
234
235       TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire();
236
237       Handle(AIS_Shape) aShape = new AIS_Shape( aWire );
238       aSectionRepresentation.push_back( aShape );
239     }
240   }
241   return aSectionRepresentation;
242 }
243
244 //=======================================================================
245 // function: setUndoDepth
246 // purpose:
247 //=======================================================================
248 void CurveCreator_Curve::setUndoDepth(const int theDepth)
249 {
250   if (theDepth == 0) {
251     // Reset all undo/redo data.
252     myNbUndos = 0;
253     myNbRedos = 0;
254     myListDiffs.clear();
255     myCurrenPos = myListDiffs.end();
256     myUndoDepth = 0;
257   } else if (theDepth == -1) {
258     // There is nothing to do as the depth become unlimited.
259     myUndoDepth = -1;
260   } else if (theDepth > 0) {
261     // The new "real" depth is set.
262     if (theDepth < myNbRedos) {
263       // The new depth is less then number of redos. Remove the latest redos.
264       int aShift = (myNbRedos - theDepth);
265       ListDiff::iterator aFromPos = myListDiffs.end();
266
267       while (aShift--) {
268         aFromPos--;
269       }
270
271       myListDiffs.erase(aFromPos, myListDiffs.end());
272       myNbRedos = theDepth;
273     }
274
275     if (theDepth < myNbUndos + myNbRedos) {
276       // The new depth is less then the total number of differences.
277       // Remove the first undos.
278       int aShift = (myNbUndos + myNbRedos - theDepth);
279       ListDiff::iterator aToPos = myListDiffs.begin();
280
281       while (aShift--) {
282         aToPos++;
283       }
284
285       myListDiffs.erase(myListDiffs.begin(), aToPos);
286       myNbUndos = theDepth - myNbRedos;
287     }
288
289     myUndoDepth = theDepth;
290   }
291 }
292
293 //=======================================================================
294 // function: getUndoDepth
295 // purpose:
296 //=======================================================================
297 int CurveCreator_Curve::getUndoDepth() const
298 {
299   return myUndoDepth;
300 }
301
302 Handle_AIS_Point CurveCreator_Curve::getAISPoint( int theISection, int theIPoint ) const
303 {
304   double anX, anY, aZ;
305   getCoordinates( theISection, theIPoint, anX, anY, aZ );
306   gp_Pnt aPoint( anX, anY, aZ);
307
308   AIS_Point* aPnt = new AIS_Point( new Geom_CartesianPoint(aPoint));
309   return aPnt;
310 }
311
312 Handle_AIS_Line CurveCreator_Curve::getAISLine( int theISection, int theIPoint1, int theIPoint2 ) const
313 {
314   double anX, anY, aZ;
315   getCoordinates( theISection, theIPoint1, anX, anY, aZ );
316   gp_Pnt aPoint1( anX, anY, aZ);
317
318   double anX2, anY2, aZ2;
319   getCoordinates( theISection, theIPoint2, anX2, anY2, aZ2 );
320 //MTN to avoid crash during line construction
321   if( ( anX == anX2 ) && ( anY == anY2 ) && (aZ == aZ2 ) ){
322     aZ2 += 1e-7;
323   }
324
325   gp_Pnt aPoint2( anX2, anY2, aZ2 );
326
327   AIS_Line* aLine = new AIS_Line( new Geom_CartesianPoint(aPoint1), new Geom_CartesianPoint(aPoint2) );
328   return aLine;
329 }
330
331 void CurveCreator_Curve::getCoordinates( int theISection, int theIPoint, double& theX, double& theY, double& theZ ) const
332 {
333   CurveCreator::Coordinates aCoords = getPoint( theISection, theIPoint );
334   theX = aCoords[0];
335   theY = aCoords[1];
336   theZ = 0.;
337   if( getDimension() == CurveCreator::Dim3d ){
338     theZ = aCoords[2];
339   }
340 }
341
342 void CurveCreator_Curve::redisplayCurve()
343 {
344   if( myDisplayer ) {
345     myDisplayer->erase();
346     myDisplayer->display( constructWire() );
347   }
348 }
349
350 /************   Implementation of INTERFACE methods   ************/
351
352 /***********************************************/
353 /***          Undo/Redo methods              ***/
354 /***********************************************/
355
356 //! Get number of available undo operations
357 int CurveCreator_Curve::getNbUndo() const
358 {
359   return myNbUndos;
360 }
361
362 //! Undo previous operation
363 bool CurveCreator_Curve::undo()
364 {
365   bool res = false;
366   if (myNbUndos > 0) {
367     myNbUndos--;
368     myNbRedos++;
369     myCurrenPos--;
370     myCurrenPos->applyUndo(this);
371     res = true;
372   }
373   return res;
374 }
375
376 //! Get number of available redo operations
377 int CurveCreator_Curve::getNbRedo() const
378 {
379   return myNbRedos;
380 }
381
382 //! Redo last previously "undone" operation
383 bool CurveCreator_Curve::redo()
384 {
385   bool res = false;
386   if (myNbRedos > 0) {
387     myCurrenPos->applyRedo(this);
388     myCurrenPos++;
389     myNbRedos--;
390     myNbUndos++;
391     res = true;
392   }
393   return res;
394 }
395
396 /***********************************************/
397 /***           Section methods               ***/
398 /***********************************************/
399 //=======================================================================
400 // function: clear
401 // purpose:
402 //=======================================================================
403 bool CurveCreator_Curve::clear()
404 {
405   // erase curve from the viewer
406   if( myDisplayer )
407     myDisplayer->erase();
408   // Delete all allocated data.
409   int i = 0;
410   const int aNbSections = getNbSections();
411
412   for (; i < aNbSections; i++) {
413     delete mySections[i];
414   }
415
416   mySections.clear();
417   
418   return true;
419 }
420
421 //! Join range of sections to one section (join all sections if -1 is passed in one of arguments)
422 bool CurveCreator_Curve::join( const int theISectionTo, 
423                    const int theISectionFrom )
424 {
425   if (theISectionTo != theISectionFrom) {
426     startOperation();
427     if (addEmptyDiff())
428       myListDiffs.back().init(this, CurveCreator_Operation::Join, theISectionTo, theISectionFrom);
429
430     CurveCreator_Section *aSection1 = mySections.at(theISectionTo);
431     CurveCreator_Section *aSection2 = mySections.at(theISectionFrom);
432
433     aSection1->myPoints.insert(aSection1->myPoints.end(),
434                                aSection2->myPoints.begin(), 
435                                aSection2->myPoints.end());
436
437     removeSection(theISectionFrom);
438     redisplayCurve();
439
440     finishOperation();
441     return true;
442   }
443   return false;
444 }
445
446 //! Get number of sections
447 int CurveCreator_Curve::getNbSections() const
448 {
449   return mySections.size();
450 }
451
452 //! For internal use only! Undo/Redo is not used here.
453 int CurveCreator_Curve::addSectionInternal
454         (const std::string& theName, const CurveCreator::SectionType theType,
455          const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
456 {
457   CurveCreator_Section *aSection = new CurveCreator_Section;
458
459   std::string aName = theName;
460   if( aName.empty() ){
461       aName = getUniqSectionName();
462   }
463   aSection->myName     = aName;
464   aSection->myType     = theType;
465   aSection->myIsClosed = theIsClosed;
466   aSection->myPoints   = thePoints;
467   mySections.push_back(aSection);
468   redisplayCurve();
469   return mySections.size()-1;
470 }
471
472 //=======================================================================
473 // function: addSection
474 // purpose: adds an empty section
475 //=======================================================================
476 int CurveCreator_Curve::addSection
477         (const std::string& theName, const CurveCreator::SectionType theType,
478          const bool theIsClosed)
479 {
480   int resISection = -1;
481   // Set the difference.
482   startOperation();
483   CurveCreator::Coordinates aCoords; //empty list
484   if (addEmptyDiff()) {
485     myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
486                             theName, aCoords, theType, theIsClosed);
487   }
488
489   resISection = addSectionInternal(theName, theType, theIsClosed, aCoords);
490
491   finishOperation();
492   return resISection;
493 }
494 //=======================================================================
495 // function: addSection
496 // purpose: adds a section with the given points
497 //=======================================================================
498 int CurveCreator_Curve::addSection
499         (const std::string& theName, const CurveCreator::SectionType theType,
500          const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
501 {
502   int resISection = -1;
503   // Set the difference.
504   startOperation();
505   if (addEmptyDiff()) {
506     myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
507                             theName, thePoints, theType, theIsClosed);
508   }
509
510   resISection = addSectionInternal(theName, theType, theIsClosed, thePoints);
511
512   finishOperation();
513   return resISection;
514 }
515
516 bool CurveCreator_Curve::removeSectionInternal( const int theISection )
517 {
518   if (theISection == -1) {
519     delete mySections.back();
520     mySections.pop_back();
521   } else {
522     CurveCreator::Sections::iterator anIterRm = mySections.begin() + theISection;
523
524     delete *anIterRm;
525     mySections.erase(anIterRm);
526   }
527   redisplayCurve();
528   return true;
529 }
530   
531 //! Removes the given sections.
532 bool CurveCreator_Curve::removeSection( const int theISection )
533 {
534   bool res = false;
535   // Set the difference.
536   startOperation();
537   if (addEmptyDiff())
538     myListDiffs.back().init(this, CurveCreator_Operation::RemoveSection, theISection);
539
540   res = removeSectionInternal( theISection );
541
542   finishOperation();
543   return res;
544 }
545
546 /**
547  *  Get number of points in specified section or (the total number of points
548  *  in Curve if theISection is equal to -1).
549  */
550 int CurveCreator_Curve::getNbPoints( const int theISection ) const
551 {
552   int aNbCoords = 0;
553
554   if (theISection == -1) {
555     int i = 0;
556     const int aNbSections = getNbSections();
557
558     for (; i < aNbSections; i++) {
559       aNbCoords += mySections[i]->myPoints.size();
560     }
561   } else {
562     aNbCoords = mySections.at(theISection)->myPoints.size();
563   }
564
565   return aNbCoords/myDimension;
566 }
567
568 //! Get "closed" flag of the specified section
569 bool CurveCreator_Curve::isClosed( const int theISection ) const
570 {
571   return mySections.at(theISection)->myIsClosed;
572 }
573
574 /**
575  *  Set "closed" flag of the specified section (all sections if
576  *  \a theISection is -1).
577  */
578 bool CurveCreator_Curve::setClosed( const int theISection, 
579                         const bool theIsClosed )
580 {
581   if (theISection == -1) {
582     int aSize = mySections.size();
583     int i;
584
585     for (i = 0; i < aSize; i++) {
586       mySections[i]->myIsClosed = theIsClosed;
587       redisplayCurve();
588     }
589   } else {
590     mySections.at(theISection)->myIsClosed = theIsClosed;
591     redisplayCurve();
592   }
593   return true;
594 }
595
596 //! Returns specified section name
597 std::string CurveCreator_Curve::getSectionName( const int theISection ) const
598 {
599   if( ( theISection >= 0 ) && ( theISection < mySections.size() ))
600     return mySections.at(theISection)->myName;
601   return "";
602 }
603
604 /** Set name of the specified section */
605 bool CurveCreator_Curve::setSectionName
606   ( const int theISection, const std::string& theName )
607 {
608   if( ( theISection >= 0 ) && ( theISection < mySections.size() )){
609     mySections.at(theISection)->myName = theName;
610     return true;
611   }
612   return false;
613 }
614
615 //! Get type of the specified section
616 CurveCreator::SectionType CurveCreator_Curve::getSectionType
617   ( const int theISection ) const
618 {
619   return mySections.at(theISection)->myType;
620 }
621
622 /**
623  *  Set type of the specified section (or all sections
624  *  if \a theISection is -1).
625  */
626 bool CurveCreator_Curve::setSectionType( const int theISection, 
627                                          const CurveCreator::SectionType theType )
628 {
629   if (theISection == -1) {
630     int i = 0;
631     const int aNbSections = getNbSections();
632
633     for (; i < aNbSections; i++) {
634       mySections[i]->myType = theType;
635     }
636     redisplayCurve();
637   } else {
638     if( mySections.at(theISection)->myType != theType ){
639       mySections.at(theISection)->myType = theType;
640       redisplayCurve();
641     }
642   }
643   return true;
644 }
645
646
647 /***********************************************/
648 /***           Point methods                 ***/
649 /***********************************************/
650
651 //! For internal use only! Undo/Redo is not used here.
652 bool CurveCreator_Curve::addPointsInternal( const CurveCreator::Coordinates& theCoords,
653                                             const std::vector<int> &theISections,
654                                             const std::vector<int> &theIPnts  )
655 {
656   bool res = false;
657   if( (theCoords.size()/getDimension()) == theISections.size() == theIPnts.size() ) {
658     for( int ind = 0; ind < theISections.size(); ind++ ) {
659       int anISection = theISections.at(ind);
660       CurveCreator_Section *aSection =
661         (anISection == -1 ? mySections.back() : mySections.at(anISection));
662
663       if( aSection ) {
664         int anIPnt = theIPnts.at(ind);
665         CurveCreator::Coordinates::iterator anIterPosition;
666         if(anIPnt == -1)
667           anIterPosition = aSection->myPoints.end();
668         else
669           anIterPosition = aSection->myPoints.begin() + toICoord(anIPnt);
670         CurveCreator::Coordinates::const_iterator aFirstPosition = 
671           theCoords.begin() + toICoord(ind);        
672         aSection->myPoints.insert(anIterPosition,
673                                   aFirstPosition, 
674                                   aFirstPosition + getDimension());
675         res = true;
676       }
677     }
678     if(res)
679       redisplayCurve();
680   }
681   return res;
682 }
683
684 /**
685  *  Add one point to the specified section starting from the given theIPnt index
686  *  (or at the end of points if \a theIPnt is -1).
687  */
688 bool CurveCreator_Curve::addPoints( const CurveCreator::Coordinates& theCoords,
689                                     const int theISection,
690                                     const int theIPnt )
691 {
692   bool res = false;
693   CurveCreator::Coordinates aCoords = theCoords;
694   // Set the difference.
695   startOperation();
696   if (addEmptyDiff()) {
697     myListDiffs.back().init(this, CurveCreator_Operation::InsertPoints,
698                             theCoords, theISection, theIPnt);
699   }
700   std::vector<int> anISections, anIPnts;
701   anISections.push_back( theISection );
702   anIPnts.push_back( theIPnt );
703   res = addPointsInternal( theCoords, anISections, anIPnts );
704   finishOperation();
705   return res;
706 }
707
708 //! Set coordinates of specified point
709 bool CurveCreator_Curve::setPoint( const int theISection,
710                                    const int theIPnt,
711                                    const CurveCreator::Coordinates& theNewCoords )
712 {
713   // Set the difference.
714   startOperation();
715   if (addEmptyDiff()) {
716     myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
717                             theNewCoords, theISection, theIPnt);
718   }
719
720   bool res = false;
721
722   // Update the curve.
723   if (theNewCoords.size() == myDimension) {
724     CurveCreator_Section *aSection = mySections.at(theISection);
725     int i;
726     for (i = 0; i < myDimension; i++) {
727       aSection->myPoints.at(toICoord(theIPnt) + i) = theNewCoords[i];
728     }
729     redisplayCurve();
730     
731     res = true;
732   }
733
734   finishOperation();
735
736   return res; 
737 }
738
739 bool CurveCreator_Curve::removePointsInternal( const std::vector<int> &theISections, 
740                                                const std::vector<int> &theIPnts )
741 {
742   bool res = false;
743   if( theISections.size() == theIPnts.size() ) {
744     for( int ind = 0; ind < theISections.size(); ind++ ) {
745       int anISection = theISections.at(ind);
746       CurveCreator_Section *aSection = mySections.at(anISection);
747       if( aSection ) {
748         int anIPnt = theIPnts.at(ind);
749         CurveCreator::Coordinates::iterator aFirstPosition;
750         if(anIPnt == -1)
751           aFirstPosition = aSection->myPoints.end();
752         else
753           aFirstPosition = aSection->myPoints.begin() + toICoord(anIPnt);
754         aSection->myPoints.erase( aFirstPosition, aFirstPosition + getDimension() );
755         res = true;
756       }
757     }
758     if(res)
759       redisplayCurve();
760   }
761   return res;
762 }
763
764 //! Remove point with given id
765 bool CurveCreator_Curve::removePoint( const int theISection, const int theIPnt )
766 {
767   bool res = false;
768   // Set the difference.
769   startOperation();
770   if (addEmptyDiff()) {
771     myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
772                             theISection, theIPnt);
773   }
774   std::vector<int> anISections, anIPnts;
775   anISections.push_back( theISection );
776   anIPnts.push_back( theIPnt );
777   res = removePointsInternal( anISections, anIPnts );
778   finishOperation();
779   return res;
780 }
781
782 //=======================================================================
783 // function: getCoordinates
784 // purpose:
785 //=======================================================================
786 CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection,
787                                                         const int theIPnt) const
788 {
789   CurveCreator_Section *aSection = mySections.at(theISection);
790   CurveCreator::Coordinates::const_iterator
791     anIter = aSection->myPoints.begin() + toICoord(theIPnt);
792   CurveCreator::Coordinates aResult(anIter, anIter + myDimension);
793
794   return aResult;
795 }
796
797 //=======================================================================
798 // function: getPoints
799 // purpose:
800 //=======================================================================
801 CurveCreator::Coordinates CurveCreator_Curve::getPoints( const int theISection ) const
802 {
803   return mySections.at(theISection)->myPoints;
804 }
805
806
807 /***********************************************/
808 /***       Presentation methods              ***/
809 /***********************************************/
810 std::vector<Handle_AIS_InteractiveObject> CurveCreator_Curve::constructWire() const
811 {
812   std::vector<Handle_AIS_InteractiveObject> aCurveRepresentation;
813   std::vector<Handle_AIS_InteractiveObject> aSectionObjects;
814   for( int iSection = 0 ; iSection < getNbSections() ; iSection++ ){
815     aSectionObjects = constructSection( iSection );
816     for( int iObject = 0 ; iObject < aSectionObjects.size() ; iObject++ ){
817       aCurveRepresentation.push_back( aSectionObjects.at(iObject) );
818     }
819   }
820   return aCurveRepresentation;
821 }