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