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_Diff.cxx
21 // Author: Sergey KHROMOV
23 #include "CurveCreator_Diff.hxx"
24 #include "CurveCreator_Curve.hxx"
28 //=======================================================================
29 // function: Constructor
31 //=======================================================================
32 CurveCreator_Diff::CurveCreator_Diff()
39 //=======================================================================
40 // function: Destructor
42 //=======================================================================
43 CurveCreator_Diff::~CurveCreator_Diff()
48 //=======================================================================
51 //=======================================================================
52 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
53 const CurveCreator_Operation::Type theType)
57 if (theCurve != NULL) {
61 myPRedo = new CurveCreator_Operation;
63 if (myPRedo->init(theType)) {
66 const int aNbSections = theCurve->getNbSections();
68 if (theType == CurveCreator_Operation::Clear) {
69 // Construct undo for Clear command.
70 if (aNbSections > 0) {
71 setNbUndos(aNbSections);
73 for (int i = 0; i < aNbSections && isOK; i++) {
74 // Add AddSection command.
75 isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
78 } else { // theType == CurveCreator_Operation::Join
79 // Construct undo for Join command.
80 if (aNbSections > 1) {
81 // Add the RemovePoints command to remove points of
82 // the second section fron the first one.
83 const int aNbPoints = theCurve->getNbPoints(0);
85 setNbUndos(aNbSections);
86 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
89 for (int i = 1; i < aNbSections && isOK; i++) {
90 // Add AddSection command.
91 isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
105 //=======================================================================
108 //=======================================================================
109 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
110 const CurveCreator_Operation::Type theType,
111 const int theIntParam)
115 if (theCurve != NULL) {
119 myPRedo = new CurveCreator_Operation;
121 if (myPRedo->init(theType, theIntParam)) {
122 // Construct undo for RemoveSection command.
123 // If the last section is removed, one AddSection command is enough.
124 // If not last section is removed, two commands are requred: AddSection
126 const int aLastIndex = theCurve->getNbSections() - 1;
128 if (theIntParam == aLastIndex) {
134 isOK = addSectionToUndo(theCurve, theIntParam, myPUndo[0]);
136 if (isOK && theIntParam != aLastIndex) {
137 isOK = myPUndo[1].init(CurveCreator_Operation::MoveSection,
138 aLastIndex, theIntParam);
150 //=======================================================================
153 //=======================================================================
154 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
155 const CurveCreator_Operation::Type theType,
156 const int theIntParam1,
157 const int theIntParam2)
161 if (theCurve != NULL) {
165 myPRedo = new CurveCreator_Operation;
167 if (myPRedo->init(theType, theIntParam1, theIntParam2)) {
168 // Construct undo for different commands.
170 case CurveCreator_Operation::SetType:
171 case CurveCreator_Operation::SetClosed:
172 isOK = setTypeOrClosedToUndo
173 (theCurve, theType, theIntParam1, theIntParam2);
175 case CurveCreator_Operation::MoveSection:
177 isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
179 case CurveCreator_Operation::Join:
181 // If the last section is removed, one AddSection command is
182 // enough. If not last section is removed, two commands are
183 // requred: AddSection and MoveSection.
184 const int aLastIndex = theCurve->getNbSections() - 1;
185 const int aNbPoints = theCurve->getNbPoints(theIntParam1);
187 if (theIntParam2 == aLastIndex) {
193 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
194 theIntParam1, aNbPoints, -1);
197 isOK = addSectionToUndo(theCurve, theIntParam2, myPUndo[1]);
199 if (isOK && theIntParam2 != aLastIndex) {
200 isOK = myPUndo[2].init(CurveCreator_Operation::MoveSection,
201 aLastIndex, theIntParam2);
219 //=======================================================================
222 //=======================================================================
223 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
224 const CurveCreator_Operation::Type theType,
225 const int theIntParam1,
226 const int theIntParam2,
227 const int theIntParam3)
231 if (theCurve != NULL) {
235 myPRedo = new CurveCreator_Operation;
237 if (myPRedo->init(theType, theIntParam1, theIntParam2, theIntParam3)) {
248 //=======================================================================
251 //=======================================================================
252 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
253 const CurveCreator_Operation::Type theType,
254 const CurveCreator::Coordinates &theCoords,
255 const int theIntParam)
259 if (theCurve != NULL) {
263 myPRedo = new CurveCreator_Operation;
265 if (myPRedo->init(theType, theCoords, theIntParam)) {
266 // Construct undo for AddPoints command.
267 const int aSectionInd = getSectionIndex(theCurve, theIntParam);
268 const CurveCreator::Dimension aDim = theCurve->getDimension();
269 const CurveCreator::Coordinates &aPoints =
270 theCurve->getPoints(aSectionInd);
271 const int aNbPoints = (aPoints.size()/aDim);
274 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
275 aSectionInd, aNbPoints, -1);
286 //=======================================================================
289 //=======================================================================
290 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
291 const CurveCreator_Operation::Type theType,
292 const std::string& theName,
293 const CurveCreator::Coordinates &theCoords,
294 const int theIntParam1,
295 const int theIntParam2)
299 if (theCurve != NULL) {
303 myPRedo = new CurveCreator_Operation;
305 if (myPRedo->init(theType, theName, theCoords, theIntParam1, theIntParam2)) {
306 // Construct undo for different commands.
308 case CurveCreator_Operation::AddSection:
310 isOK = myPUndo[0].init(CurveCreator_Operation::RemoveSection, -1);
320 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
321 const CurveCreator_Operation::Type theType,
322 const std::string &theName,
323 const int theIntParam1 )
326 myPRedo = new CurveCreator_Operation;
328 if (myPRedo->init(theType, theName, theIntParam1 )) {
329 // Construct undo for different commands.
331 case CurveCreator_Operation::RenameSection:
333 isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
334 theCurve->getSectionName(theIntParam1), theIntParam1);
344 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
345 const CurveCreator_Operation::Type theType,
346 const CurveCreator_ICurve::SectionToPointList &theParamList1)
350 if (theCurve != NULL) {
354 myPRedo = new CurveCreator_Operation;
356 if (myPRedo->init(theType, theParamList1)) {
357 // Construct undo for different commands.
359 case CurveCreator_Operation::RemovePoints:
361 // Construct undo for RemovePoints command.
362 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointCoords;
363 CurveCreator::Coordinates aPointsToAdd;
364 const CurveCreator::Dimension aDim = theCurve->getDimension();
365 CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
366 std::list<int> aPoints;
367 int aSectionId, aPointId;
368 for ( ; anIt != aLast; anIt++ ) {
369 aPointsToAdd.clear();
370 aSectionId = anIt->first;
371 aPointId = anIt->second;
372 const CurveCreator::Coordinates &aPoints =
373 theCurve->getPoints(aSectionId);
374 CurveCreator::Coordinates::const_iterator anIterBegin =
375 aPoints.begin() + (aDim*aPointId);
376 CurveCreator::Coordinates::const_iterator anIterEnd =
378 aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
379 aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
382 isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
383 aSectionToPointCoords);
399 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
400 const CurveCreator_Operation::Type theType,
401 const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
405 if (theCurve != NULL) {
409 myPRedo = new CurveCreator_Operation;
411 if (myPRedo->init(theType, theParamList1)) {
412 // Construct undo for different commands.
414 case CurveCreator_Operation::InsertPoints:
416 // Construct undo for RemovePoints command.
417 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
418 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
419 int aSectionId, aPointId;
420 for ( ; anIt != aLast; anIt++ ) {
421 aSectionToPointList.push_back(anIt->first);
424 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
425 aSectionToPointList);
428 case CurveCreator_Operation::SetCoordinates:
430 // Construct undo for SetCoordinates command.
431 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
432 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
433 for ( ; anIt != aLast; anIt++ ) {
434 CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
435 aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
439 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
440 aSectionToPointOldCoords);
456 //=======================================================================
457 // function: applyUndo
459 //=======================================================================
460 void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
462 if (myNbUndos > 0 && myPUndo != NULL) {
463 for (int i = 0; i < myNbUndos; i++) {
464 myPUndo[i].apply(theCurve);
469 //=======================================================================
470 // function: applyRedo
472 //=======================================================================
473 void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
475 if (myPRedo != NULL) {
476 myPRedo->apply(theCurve);
480 //=======================================================================
483 //=======================================================================
484 void CurveCreator_Diff::clear()
486 if (myPUndo != NULL) {
493 if (myPRedo != NULL) {
499 //=======================================================================
500 // function: setNbUndos
502 //=======================================================================
503 void CurveCreator_Diff::setNbUndos(const int theNbUndos)
505 myNbUndos = theNbUndos;
506 myPUndo = new CurveCreator_Operation[myNbUndos];
509 //=======================================================================
510 // function: getSectionIndex
512 //=======================================================================
513 int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
514 const int theIndex) const
516 return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
519 //=======================================================================
520 // function: addSectionToUndo
522 //=======================================================================
523 bool CurveCreator_Diff::addSectionToUndo
524 (const CurveCreator_Curve *theCurve,
526 CurveCreator_Operation &theOperation) const
528 const std::string aName = theCurve->getSectionName(theIndex);
529 const CurveCreator::Coordinates &aPnts = theCurve->getPoints(theIndex);
530 const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
531 const bool isClosed = theCurve->isClosed(theIndex);
533 bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
534 aName, aPnts, aType, isClosed);
539 //=======================================================================
540 // function: setTypeOrClosedToUndo
542 //=======================================================================
543 bool CurveCreator_Diff::setTypeOrClosedToUndo
544 (const CurveCreator_Curve *theCurve,
545 const CurveCreator_Operation::Type theType,
546 const int theIntParam1,
547 const int theIntParam2)
551 // Compute number of modified sections.
552 const bool isSetType = (theType == CurveCreator_Operation::SetType);
554 std::list<int> aListOfInd;
558 if (theIntParam2 == -1) {
559 // The operation is applied to all sections. We need to collect
560 // really modified sections for undo.
561 const int aNbSections = theCurve->getNbSections();
563 if (aNbSections > 0) {
564 // Get sections to be modified.
565 for (i = 0; i < aNbSections; i++) {
567 aValue = theCurve->getSectionType(i);
569 aValue = theCurve->isClosed(i);
572 if (theIntParam1 != aValue) {
574 aListOfInd.push_back(i);
578 if (aNbSections == aNbModif) {
579 // All sections are modified. We can use one single command
580 // with -1 section index.
583 aListOfInd.push_back(-1);
587 // There is only particular section modified.
588 // Check if there is a real modification required.
590 aValue = theCurve->getSectionType(theIntParam2);
592 aValue = theCurve->isClosed(theIntParam2);
595 if (theIntParam1 != aValue) {
597 aListOfInd.push_back(theIntParam2);
603 std::list<int>::iterator anIter = aListOfInd.begin();
606 aValue = theCurve->getSectionType(*anIter);
608 aValue = theCurve->isClosed(*anIter);
611 setNbUndos(aNbModif);
613 for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
614 isOK = myPUndo[i].init(theType, aValue, *anIter);