1 // Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: CurveCreator_Curve.cxx
21 // Author: Sergey KHROMOV
23 #include "CurveCreator_Curve.hxx"
25 #include "CurveCreator.hxx"
26 #include "CurveCreator_Section.hxx"
27 #include "CurveCreator_Listener.hxx"
31 //=======================================================================
32 // function: Constructor
34 //=======================================================================
35 CurveCreator_Curve::CurveCreator_Curve( const CurveCreator::Dimension theDimension )
37 myDimension (theDimension),
46 //=======================================================================
47 // function: Destructor
49 //=======================================================================
50 CurveCreator_Curve::~CurveCreator_Curve()
52 // Delete all allocated data.
56 //=======================================================================
57 // function: getDimension
59 //=======================================================================
60 CurveCreator::Dimension CurveCreator_Curve::getDimension() const
65 //=======================================================================
66 // function: getUniqSectionName
67 // purpose: return unique section name
68 //=======================================================================
69 std::string CurveCreator_Curve::getUniqSectionName() const
71 for( int i = 0 ; i < 1000000 ; i++ ){
73 sprintf( aBuffer, "Section_%d", i+1 );
74 std::string aName(aBuffer);
76 for( j = 0 ; j < mySections.size() ; j++ ){
77 if( mySections[j]->myName == aName )
80 if( j == mySections.size() )
86 //=======================================================================
87 // function: setListener
88 // purpose: set curve changes listener
89 //=======================================================================
90 void CurveCreator_Curve::setListener( CurveCreator_Listener* theListener )
92 myListener = theListener;
95 //=======================================================================
96 // function: removeListener
97 // purpose: remove the attached listener
98 //=======================================================================
99 void CurveCreator_Curve::removeListener()
104 //=======================================================================
107 //=======================================================================
108 bool CurveCreator_Curve::addEmptyDiff()
110 bool isEnabled = false;
112 if (myUndoDepth != 0) {
113 // Forget all Redos after the current one.
116 myListDiffs.erase(myCurrenPos, myListDiffs.end());
119 if (myUndoDepth == -1 || myNbUndos < myUndoDepth) {
120 // Increase the number of undos.
123 // If there are too many differences, remove the first one.
124 myListDiffs.pop_front();
127 // Add new difference.
128 myListDiffs.push_back(CurveCreator_Diff());
129 myCurrenPos = myListDiffs.end();
136 void CurveCreator_Curve::startOperation()
141 void CurveCreator_Curve::finishOperation()
146 //=======================================================================
147 // function: toICoord
149 //=======================================================================
150 int CurveCreator_Curve::toICoord(const int theIPnt) const
152 return theIPnt * myDimension;
155 //=======================================================================
156 // function: setUndoDepth
158 //=======================================================================
159 void CurveCreator_Curve::setUndoDepth(const int theDepth)
162 // Reset all undo/redo data.
166 myCurrenPos = myListDiffs.end();
168 } else if (theDepth == -1) {
169 // There is nothing to do as the depth become unlimited.
171 } else if (theDepth > 0) {
172 // The new "real" depth is set.
173 if (theDepth < myNbRedos) {
174 // The new depth is less then number of redos. Remove the latest redos.
175 int aShift = (myNbRedos - theDepth);
176 ListDiff::iterator aFromPos = myListDiffs.end();
182 myListDiffs.erase(aFromPos, myListDiffs.end());
183 myNbRedos = theDepth;
186 if (theDepth < myNbUndos + myNbRedos) {
187 // The new depth is less then the total number of differences.
188 // Remove the first undos.
189 int aShift = (myNbUndos + myNbRedos - theDepth);
190 ListDiff::iterator aToPos = myListDiffs.begin();
196 myListDiffs.erase(myListDiffs.begin(), aToPos);
197 myNbUndos = theDepth - myNbRedos;
200 myUndoDepth = theDepth;
204 //=======================================================================
205 // function: getUndoDepth
207 //=======================================================================
208 int CurveCreator_Curve::getUndoDepth() const
213 /************ Implementation of INTERFACE methods ************/
215 /***********************************************/
216 /*** Undo/Redo methods ***/
217 /***********************************************/
219 //! Get number of available undo operations
220 int CurveCreator_Curve::getNbUndo() const
225 //! Undo previous operation
226 bool CurveCreator_Curve::undo()
233 myCurrenPos->applyUndo(this);
239 //! Get number of available redo operations
240 int CurveCreator_Curve::getNbRedo() const
245 //! Redo last previously "undone" operation
246 bool CurveCreator_Curve::redo()
250 myCurrenPos->applyRedo(this);
259 /***********************************************/
260 /*** Section methods ***/
261 /***********************************************/
262 //=======================================================================
265 //=======================================================================
266 bool CurveCreator_Curve::clear()
268 // Delete all allocated data.
270 const int aNbSections = getNbSections();
272 for (; i < aNbSections; i++) {
273 delete mySections[i];
278 myListener->curveChanged();
283 //! Join range of sections to one section (join all sections if -1 is passed in one of arguments)
284 bool CurveCreator_Curve::join( const int theISectionTo,
285 const int theISectionFrom )
287 if (theISectionTo != theISectionFrom) {
290 myListDiffs.back().init(this, CurveCreator_Operation::Join, theISectionTo, theISectionFrom);
292 CurveCreator_Section *aSection1 = mySections.at(theISectionTo);
293 CurveCreator_Section *aSection2 = mySections.at(theISectionFrom);
295 aSection1->myPoints.insert(aSection1->myPoints.end(),
296 aSection2->myPoints.begin(),
297 aSection2->myPoints.end());
299 removeSection(theISectionFrom);
301 myListener->curveChanged();
309 //! Get number of sections
310 int CurveCreator_Curve::getNbSections() const
312 return mySections.size();
315 //=======================================================================
316 // function: addSection
317 // purpose: adds an empty section
318 //=======================================================================
319 int CurveCreator_Curve::addSection
320 (const std::string& theName, const CurveCreator::SectionType theType,
321 const bool theIsClosed)
323 int resISection = -1;
324 // Set the difference.
326 if (addEmptyDiff()) {
327 CurveCreator::Coordinates aCoords; //empty list
328 myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
329 theName, aCoords, theType, theIsClosed);
331 CurveCreator_Section *aSection = new CurveCreator_Section;
333 std::string aName = theName;
335 aName = getUniqSectionName();
337 aSection->myName = aName;
338 aSection->myType = theType;
339 aSection->myIsClosed = theIsClosed;
340 mySections.push_back(aSection);
342 myListener->sectionAdded( -1 );
345 return mySections.size()-1;
347 //=======================================================================
348 // function: addSection
349 // purpose: adds a section with the given points
350 //=======================================================================
351 int CurveCreator_Curve::addSection
352 (const std::string& theName, const CurveCreator::SectionType theType,
353 const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
355 int resISection = -1;
356 //// Set the difference.
358 //if (addEmptyDiff()) {
359 // myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
360 // theName, thePoints, theType, theIsClosed);
363 // create an empty section
364 resISection = addSection(theName, theType, theIsClosed);
365 if( resISection != -1 ) {
366 // attach the given points to created section
367 CurveCreator_Section *aSection = mySections.at(resISection);
368 aSection->myPoints = thePoints;
375 //! Removes the given sections.
376 bool CurveCreator_Curve::removeSection( const int theISection )
378 // Set the difference.
381 myListDiffs.back().init(this, CurveCreator_Operation::RemoveSection, theISection);
383 if (theISection == -1) {
384 delete mySections.back();
385 mySections.pop_back();
387 CurveCreator::Sections::iterator anIterRm = mySections.begin() + theISection;
390 mySections.erase(anIterRm);
393 myListener->sectionRemoved(theISection);
400 * Get number of points in specified section or (the total number of points
401 * in Curve if theISection is equal to -1).
403 int CurveCreator_Curve::getNbPoints( const int theISection ) const
407 if (theISection == -1) {
409 const int aNbSections = getNbSections();
411 for (; i < aNbSections; i++) {
412 aNbCoords += mySections[i]->myPoints.size();
415 aNbCoords = mySections.at(theISection)->myPoints.size();
418 return aNbCoords/myDimension;
421 //! Get "closed" flag of the specified section
422 bool CurveCreator_Curve::isClosed( const int theISection ) const
424 return mySections.at(theISection)->myIsClosed;
428 * Set "closed" flag of the specified section (all sections if
429 * \a theISection is -1).
431 bool CurveCreator_Curve::setClosed( const int theISection,
432 const bool theIsClosed )
434 if (theISection == -1) {
435 int aSize = mySections.size();
438 for (i = 0; i < aSize; i++) {
439 mySections[i]->myIsClosed = theIsClosed;
441 myListener->sectionClosed( theISection, theIsClosed );
445 mySections.at(theISection)->myIsClosed = theIsClosed;
447 myListener->sectionClosed( theISection, theIsClosed );
453 //! Returns specifyed section name
454 std::string CurveCreator_Curve::getSectionName( const int theISection ) const
456 if( ( theISection >= 0 ) && ( theISection < mySections.size() ))
457 return mySections.at(theISection)->myName;
461 /** Set name of the specified section */
462 bool CurveCreator_Curve::setSectionName
463 ( const int theISection, const std::string& theName )
465 if( ( theISection >= 0 ) && ( theISection < mySections.size() )){
466 mySections.at(theISection)->myName = theName;
472 //! Get type of the specified section
473 CurveCreator::SectionType CurveCreator_Curve::getSectionType
474 ( const int theISection ) const
476 return mySections.at(theISection)->myType;
480 * Set type of the specified section (or all sections
481 * if \a theISection is -1).
483 bool CurveCreator_Curve::setSectionType( const int theISection,
484 const CurveCreator::SectionType theType )
486 if (theISection == -1) {
488 const int aNbSections = getNbSections();
490 for (; i < aNbSections; i++) {
491 mySections[i]->myType = theType;
494 myListener->curveChanged();
496 if( mySections.at(theISection)->myType != theType ){
497 mySections.at(theISection)->myType = theType;
499 myListener->sectionTypeChanged(theISection);
506 /***********************************************/
507 /*** Point methods ***/
508 /***********************************************/
511 * Add one point to the specified section starting from the given theIPnt index
512 * (or at the end of points if \a theIPnt is -1).
514 bool CurveCreator_Curve::addPoints( const CurveCreator::Coordinates& theCoords,
515 const int theISection,
519 CurveCreator::Coordinates aCoords = theCoords;
520 // Set the difference.
522 if (addEmptyDiff()) {
523 myListDiffs.back().init(this, CurveCreator_Operation::AddPoints,
524 theCoords, theISection);
526 CurveCreator_Section *aSection =
527 (theISection == -1 ? mySections.back() : mySections.at(theISection));
530 int anICoord = ( theIPnt == -1 ? 0 : toICoord(theIPnt) );
531 CurveCreator::Coordinates::iterator anIterPosition = aSection->myPoints.end();
533 anIterPosition = aSection->myPoints.begin() + toICoord(theIPnt);
534 aSection->myPoints.insert(anIterPosition,
535 theCoords.begin(), theCoords.end());
537 myListener->pointInserted( theISection, -1 );
544 //! Set coordinates of specified point
545 bool CurveCreator_Curve::setPoint( const int theISection,
547 const CurveCreator::Coordinates& theNewCoords )
549 // Set the difference.
551 if (addEmptyDiff()) {
552 myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
553 theNewCoords, theISection, theIPnt);
559 if (theNewCoords.size() == myDimension) {
560 CurveCreator_Section *aSection = mySections.at(theISection);
562 for (i = 0; i < myDimension; i++) {
563 aSection->myPoints.at(toICoord(theIPnt) + i) = theNewCoords[i];
566 myListener->pointChanged( theISection, theIPnt );
576 //! Remove point with given id
577 bool CurveCreator_Curve::removePoint( const int theISection, const int theIPnt )
580 // Set the difference.
582 if (addEmptyDiff()) {
583 myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
584 theISection, theIPnt, 0);
586 CurveCreator_Section *aSection = mySections.at(theISection);
588 CurveCreator::Coordinates::iterator anIterPosition =
589 aSection->myPoints.begin() + toICoord(theIPnt);
590 aSection->myPoints.erase( anIterPosition );
592 myListener->pointRemoved( theISection, theIPnt );
599 //=======================================================================
600 // function: getCoordinates
602 //=======================================================================
603 CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection,
604 const int theIPnt) const
606 CurveCreator_Section *aSection = mySections.at(theISection);
607 CurveCreator::Coordinates::const_iterator
608 anIter = aSection->myPoints.begin() + toICoord(theIPnt);
609 CurveCreator::Coordinates aResult(anIter, anIter + myDimension);
614 //=======================================================================
615 // function: getPoints
617 //=======================================================================
618 CurveCreator::Coordinates CurveCreator_Curve::getPoints( const int theISection ) const
620 return mySections.at(theISection)->myPoints;
624 /***********************************************/
625 /*** Presentation methods ***/
626 /***********************************************/
627 /* TopoDS_Wire CurveCreator_Curve::constructWire() const