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 for ( ; anIt != aLast; anIt++ ) {
420 aSectionToPointList.push_back(anIt->first);
423 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
424 aSectionToPointList);
427 case CurveCreator_Operation::SetCoordinates:
429 // Construct undo for SetCoordinates command.
430 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
431 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
432 for ( ; anIt != aLast; anIt++ ) {
433 CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
434 aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
438 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
439 aSectionToPointOldCoords);
455 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
456 const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
460 if (theCurve != NULL && theOldParamList.size() > 0) {
464 myPRedo = new CurveCreator_Operation;
466 // Construct redo for SetCoordinates command.
467 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointActualCoords;
468 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt =
469 theOldParamList.begin(), aLast = theOldParamList.end();
470 for ( ; anIt != aLast; anIt++ ) {
471 CurveCreator::Coordinates anActualCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
472 aSectionToPointActualCoords.push_back(std::make_pair(anIt->first, anActualCoords));
475 if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
476 // Undo for SetCoordinates command.
478 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
490 //=======================================================================
491 // function: applyUndo
493 //=======================================================================
494 void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
496 if (myNbUndos > 0 && myPUndo != NULL) {
497 for (int i = 0; i < myNbUndos; i++) {
498 myPUndo[i].apply(theCurve);
503 //=======================================================================
504 // function: applyRedo
506 //=======================================================================
507 void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
509 if (myPRedo != NULL) {
510 myPRedo->apply(theCurve);
514 //=======================================================================
517 //=======================================================================
518 void CurveCreator_Diff::clear()
520 if (myPUndo != NULL) {
527 if (myPRedo != NULL) {
533 //=======================================================================
534 // function: setNbUndos
536 //=======================================================================
537 void CurveCreator_Diff::setNbUndos(const int theNbUndos)
539 myNbUndos = theNbUndos;
540 myPUndo = new CurveCreator_Operation[myNbUndos];
543 //=======================================================================
544 // function: getSectionIndex
546 //=======================================================================
547 int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
548 const int theIndex) const
550 return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
553 //=======================================================================
554 // function: addSectionToUndo
556 //=======================================================================
557 bool CurveCreator_Diff::addSectionToUndo
558 (const CurveCreator_Curve *theCurve,
560 CurveCreator_Operation &theOperation) const
562 const std::string aName = theCurve->getSectionName(theIndex);
563 const CurveCreator::Coordinates &aPnts = theCurve->getPoints(theIndex);
564 const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
565 const bool isClosed = theCurve->isClosed(theIndex);
567 bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
568 aName, aPnts, aType, isClosed);
573 //=======================================================================
574 // function: setTypeOrClosedToUndo
576 //=======================================================================
577 bool CurveCreator_Diff::setTypeOrClosedToUndo
578 (const CurveCreator_Curve *theCurve,
579 const CurveCreator_Operation::Type theType,
580 const int theIntParam1,
581 const int theIntParam2)
585 // Compute number of modified sections.
586 const bool isSetType = (theType == CurveCreator_Operation::SetType);
588 std::list<int> aListOfInd;
592 if (theIntParam2 == -1) {
593 // The operation is applied to all sections. We need to collect
594 // really modified sections for undo.
595 const int aNbSections = theCurve->getNbSections();
597 if (aNbSections > 0) {
598 // Get sections to be modified.
599 for (i = 0; i < aNbSections; i++) {
601 aValue = theCurve->getSectionType(i);
603 aValue = theCurve->isClosed(i);
606 if (theIntParam1 != aValue) {
608 aListOfInd.push_back(i);
612 if (aNbSections == aNbModif) {
613 // All sections are modified. We can use one single command
614 // with -1 section index.
617 aListOfInd.push_back(-1);
621 // There is only particular section modified.
622 // Check if there is a real modification required.
624 aValue = theCurve->getSectionType(theIntParam2);
626 aValue = theCurve->isClosed(theIntParam2);
629 if (theIntParam1 != aValue) {
631 aListOfInd.push_back(theIntParam2);
637 std::list<int>::iterator anIter = aListOfInd.begin();
640 aValue = theCurve->getSectionType(*anIter);
642 aValue = theCurve->isClosed(*anIter);
645 setNbUndos(aNbModif);
647 for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
648 isOK = myPUndo[i].init(theType, aValue, *anIter);