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