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 // Construct undo for RemovePoints command.
194 int anISection = theIntParam1;
195 const int aNbPoints2 = theCurve->getNbPoints(theIntParam2);
196 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
197 int aJoinedSize = aNbPoints + aNbPoints2;
198 for (int anIPoint = aNbPoints; anIPoint < aJoinedSize; anIPoint++)
199 aSectionToPointList.push_back(std::make_pair( anISection, anIPoint ) );
200 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
201 aSectionToPointList);
203 //isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
204 // theIntParam1, aNbPoints, -1);
207 isOK = addSectionToUndo(theCurve, theIntParam2, myPUndo[1]);
209 if (isOK && theIntParam2 != aLastIndex) {
210 isOK = myPUndo[2].init(CurveCreator_Operation::MoveSection,
211 aLastIndex, theIntParam2);
229 //=======================================================================
232 //=======================================================================
233 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
234 const CurveCreator_Operation::Type theType,
235 const int theIntParam1,
236 const int theIntParam2,
237 const int theIntParam3)
241 if (theCurve != NULL) {
245 myPRedo = new CurveCreator_Operation;
247 if (myPRedo->init(theType, theIntParam1, theIntParam2, theIntParam3)) {
258 //=======================================================================
261 //=======================================================================
262 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
263 const CurveCreator_Operation::Type theType,
264 const CurveCreator::Coordinates &theCoords,
265 const int theIntParam)
269 if (theCurve != NULL) {
273 myPRedo = new CurveCreator_Operation;
275 if (myPRedo->init(theType, theCoords, theIntParam)) {
276 // Construct undo for AddPoints command.
277 const int aSectionInd = getSectionIndex(theCurve, theIntParam);
278 const CurveCreator::Dimension aDim = theCurve->getDimension();
279 const CurveCreator::Coordinates &aPoints =
280 theCurve->getPoints(aSectionInd);
281 const int aNbPoints = (aPoints.size()/aDim);
284 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
285 aSectionInd, aNbPoints, -1);
296 //=======================================================================
299 //=======================================================================
300 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
301 const CurveCreator_Operation::Type theType,
302 const std::string& theName,
303 const CurveCreator::Coordinates &theCoords,
304 const int theIntParam1,
305 const int theIntParam2)
309 if (theCurve != NULL) {
313 myPRedo = new CurveCreator_Operation;
315 if (myPRedo->init(theType, theName, theCoords, theIntParam1, theIntParam2)) {
316 // Construct undo for different commands.
318 case CurveCreator_Operation::AddSection:
320 isOK = myPUndo[0].init(CurveCreator_Operation::RemoveSection, -1);
330 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
331 const CurveCreator_Operation::Type theType,
332 const std::string &theName,
333 const int theIntParam1 )
336 myPRedo = new CurveCreator_Operation;
338 if (myPRedo->init(theType, theName, theIntParam1 )) {
339 // Construct undo for different commands.
341 case CurveCreator_Operation::RenameSection:
343 isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
344 theCurve->getSectionName(theIntParam1), theIntParam1);
354 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
355 const CurveCreator_Operation::Type theType,
356 const CurveCreator_ICurve::SectionToPointList &theParamList1)
360 if (theCurve != NULL) {
364 myPRedo = new CurveCreator_Operation;
366 if (myPRedo->init(theType, theParamList1)) {
367 // Construct undo for different commands.
369 case CurveCreator_Operation::RemovePoints:
371 // Construct undo for RemovePoints command.
372 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointCoords;
373 CurveCreator::Coordinates aPointsToAdd;
374 const CurveCreator::Dimension aDim = theCurve->getDimension();
375 CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
376 std::list<int> aPoints;
377 int aSectionId, aPointId;
378 for ( ; anIt != aLast; anIt++ ) {
379 aPointsToAdd.clear();
380 aSectionId = anIt->first;
381 aPointId = anIt->second;
382 const CurveCreator::Coordinates &aPoints =
383 theCurve->getPoints(aSectionId);
384 CurveCreator::Coordinates::const_iterator anIterBegin =
385 aPoints.begin() + (aDim*aPointId);
386 CurveCreator::Coordinates::const_iterator anIterEnd =
388 aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
389 aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
392 isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
393 aSectionToPointCoords);
409 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
410 const CurveCreator_Operation::Type theType,
411 const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
415 if (theCurve != NULL) {
419 myPRedo = new CurveCreator_Operation;
421 if (myPRedo->init(theType, theParamList1)) {
422 // Construct undo for different commands.
424 case CurveCreator_Operation::InsertPoints:
426 // Construct undo for RemovePoints command.
427 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
428 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
429 for ( ; anIt != aLast; anIt++ ) {
430 aSectionToPointList.push_back(anIt->first);
433 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
434 aSectionToPointList);
437 case CurveCreator_Operation::SetCoordinates:
439 // Construct undo for SetCoordinates command.
440 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
441 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
442 for ( ; anIt != aLast; anIt++ ) {
443 CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
444 aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
448 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
449 aSectionToPointOldCoords);
465 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
466 const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
470 if (theCurve != NULL && theOldParamList.size() > 0) {
474 myPRedo = new CurveCreator_Operation;
476 // Construct redo for SetCoordinates command.
477 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointActualCoords;
478 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt =
479 theOldParamList.begin(), aLast = theOldParamList.end();
480 for ( ; anIt != aLast; anIt++ ) {
481 CurveCreator::Coordinates anActualCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
482 aSectionToPointActualCoords.push_back(std::make_pair(anIt->first, anActualCoords));
485 if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
486 // Undo for SetCoordinates command.
488 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
500 //=======================================================================
501 // function: applyUndo
503 //=======================================================================
504 void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
506 if (myNbUndos > 0 && myPUndo != NULL) {
507 for (int i = 0; i < myNbUndos; i++) {
508 myPUndo[i].apply(theCurve);
513 //=======================================================================
514 // function: applyRedo
516 //=======================================================================
517 void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
519 if (myPRedo != NULL) {
520 myPRedo->apply(theCurve);
524 //=======================================================================
527 //=======================================================================
528 void CurveCreator_Diff::clear()
530 if (myPUndo != NULL) {
537 if (myPRedo != NULL) {
543 //=======================================================================
544 // function: setNbUndos
546 //=======================================================================
547 void CurveCreator_Diff::setNbUndos(const int theNbUndos)
549 myNbUndos = theNbUndos;
550 myPUndo = new CurveCreator_Operation[myNbUndos];
553 //=======================================================================
554 // function: getSectionIndex
556 //=======================================================================
557 int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
558 const int theIndex) const
560 return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
563 //=======================================================================
564 // function: addSectionToUndo
566 //=======================================================================
567 bool CurveCreator_Diff::addSectionToUndo
568 (const CurveCreator_Curve *theCurve,
570 CurveCreator_Operation &theOperation) const
572 const std::string aName = theCurve->getSectionName(theIndex);
573 const CurveCreator::Coordinates &aPnts = theCurve->getPoints(theIndex);
574 const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
575 const bool isClosed = theCurve->isClosed(theIndex);
577 bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
578 aName, aPnts, aType, isClosed);
583 //=======================================================================
584 // function: setTypeOrClosedToUndo
586 //=======================================================================
587 bool CurveCreator_Diff::setTypeOrClosedToUndo
588 (const CurveCreator_Curve *theCurve,
589 const CurveCreator_Operation::Type theType,
590 const int theIntParam1,
591 const int theIntParam2)
595 // Compute number of modified sections.
596 const bool isSetType = (theType == CurveCreator_Operation::SetType);
598 std::list<int> aListOfInd;
602 if (theIntParam2 == -1) {
603 // The operation is applied to all sections. We need to collect
604 // really modified sections for undo.
605 const int aNbSections = theCurve->getNbSections();
607 if (aNbSections > 0) {
608 // Get sections to be modified.
609 for (i = 0; i < aNbSections; i++) {
611 aValue = theCurve->getSectionType(i);
613 aValue = theCurve->isClosed(i);
616 if (theIntParam1 != aValue) {
618 aListOfInd.push_back(i);
622 if (aNbSections == aNbModif) {
623 // All sections are modified. We can use one single command
624 // with -1 section index.
627 aListOfInd.push_back(-1);
631 // There is only particular section modified.
632 // Check if there is a real modification required.
634 aValue = theCurve->getSectionType(theIntParam2);
636 aValue = theCurve->isClosed(theIntParam2);
639 if (theIntParam1 != aValue) {
641 aListOfInd.push_back(theIntParam2);
647 std::list<int>::iterator anIter = aListOfInd.begin();
650 aValue = theCurve->getSectionType(*anIter);
652 aValue = theCurve->isClosed(*anIter);
655 setNbUndos(aNbModif);
657 for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
658 isOK = myPUndo[i].init(theType, aValue, *anIter);