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