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