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)
54 CurveCreator_Operation::Type aType = CurveCreator_Operation::Clear;
57 if (theCurve != NULL) {
61 myPRedo = new CurveCreator_Operation;
63 if (myPRedo->init(aType)) {
66 const int aNbSections = theCurve->getNbSections();
68 // Construct undo for Clear command.
69 if (aNbSections > 0) {
70 setNbUndos(aNbSections);
72 for (int i = 0; i < aNbSections && isOK; i++) {
73 // Add AddSection command.
74 isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
87 //=======================================================================
90 //=======================================================================
91 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
92 const CurveCreator_Operation::Type theType,
93 const int theIntParam)
97 if (theCurve != NULL) {
101 myPRedo = new CurveCreator_Operation;
103 if (myPRedo->init(theType, theIntParam)) {
104 // Construct undo for RemoveSection command.
105 // If the last section is removed, one AddSection command is enough.
106 // If not last section is removed, two commands are requred: AddSection
108 const int aLastIndex = theCurve->getNbSections() - 1;
110 if (theIntParam == aLastIndex) {
116 isOK = addSectionToUndo(theCurve, theIntParam, myPUndo[0]);
118 if (isOK && theIntParam != aLastIndex) {
119 isOK = myPUndo[1].init(CurveCreator_Operation::MoveSection,
120 aLastIndex, theIntParam);
132 //=======================================================================
135 //=======================================================================
136 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
137 const CurveCreator_Operation::Type theType,
138 const int theIntParam1,
139 const int theIntParam2)
143 if (theCurve != NULL) {
147 myPRedo = new CurveCreator_Operation;
149 if (myPRedo->init(theType, theIntParam1, theIntParam2)) {
150 // Construct undo for different commands.
152 case CurveCreator_Operation::SetType:
153 case CurveCreator_Operation::SetClosed:
154 isOK = setTypeOrClosedToUndo
155 (theCurve, theType, theIntParam1, theIntParam2);
157 case CurveCreator_Operation::MoveSection:
159 isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
174 //=======================================================================
177 //=======================================================================
178 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
179 const CurveCreator_Operation::Type theType,
180 const std::list<int>& theParams)
184 if (theCurve != NULL || theParams.empty()) {
188 myPRedo = new CurveCreator_Operation;
190 if (myPRedo->init(theType, theParams)) {
191 // Construct undo for different commands.
193 case CurveCreator_Operation::Join:
195 int aSectionMain = theParams.front();
196 const int aNbPointsMain = theCurve->getNbPoints(aSectionMain);
198 std::list<int> aSectionsToJoin = theParams;
199 aSectionsToJoin.erase( aSectionsToJoin.begin() );
200 // it is important to sort the section indices in order to correct perform undo
201 // for the move sections to the previous positions
202 aSectionsToJoin.sort();
203 // 1rst undo for remove points from the main and n-1 undoes to contain joined sections
204 int aSectionsToJoinNb = aSectionsToJoin.size();
205 int aNbUndos = 2*aSectionsToJoinNb + 1;
206 setNbUndos( aNbUndos );
208 // Add joined sections to undo
209 std::list<int>::const_iterator anIt = aSectionsToJoin.begin(),
210 aLast = aSectionsToJoin.end();
211 anIt = aSectionsToJoin.begin();
212 int aLastSectionId = -1;
213 for (int i = 0; anIt != aLast && i < aSectionsToJoinNb; anIt++, i++) {
214 int anISection = *anIt;
215 isOK = addSectionToUndo( theCurve, anISection, myPUndo[i*2] );
217 isOK = myPUndo[i*2+1].init(CurveCreator_Operation::MoveSection,
218 aLastSectionId, anISection);
223 // Construct undo for RemovePoints command.
225 int aNbPointsInJoined = 0;
226 anIt = aSectionsToJoin.begin();
227 for ( ; anIt != aLast; anIt++ )
228 aNbPointsInJoined += theCurve->getNbPoints( *anIt );
230 int aJoinedSize = aNbPointsMain + aNbPointsInJoined;
231 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
232 for (int anIPoint = aNbPointsMain; anIPoint < aJoinedSize; anIPoint++)
233 aSectionToPointList.push_back(std::make_pair(aSectionMain, anIPoint));
235 isOK = myPUndo[aNbUndos-1].init(CurveCreator_Operation::RemovePoints, aSectionToPointList);
252 //=======================================================================
255 //=======================================================================
256 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
257 const CurveCreator_Operation::Type theType,
258 const std::string& theName,
259 const CurveCreator::Coordinates &theCoords,
260 const int theIntParam1,
261 const int theIntParam2)
265 if (theCurve != NULL) {
269 myPRedo = new CurveCreator_Operation;
271 if (myPRedo->init(theType, theName, theCoords, theIntParam1, theIntParam2)) {
272 // Construct undo for different commands.
274 case CurveCreator_Operation::AddSection:
276 isOK = myPUndo[0].init(CurveCreator_Operation::RemoveSection, -1);
286 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
287 const CurveCreator_Operation::Type theType,
288 const std::string &theName,
289 const int theIntParam1 )
292 myPRedo = new CurveCreator_Operation;
294 if (myPRedo->init(theType, theName, theIntParam1 )) {
295 // Construct undo for different commands.
297 case CurveCreator_Operation::RenameSection:
299 isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
300 theCurve->getSectionName(theIntParam1), theIntParam1);
310 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
311 const CurveCreator_Operation::Type theType,
312 const CurveCreator_ICurve::SectionToPointList &theParamList1)
316 if (theCurve != NULL) {
320 myPRedo = new CurveCreator_Operation;
322 if (myPRedo->init(theType, theParamList1)) {
323 // Construct undo for different commands.
325 case CurveCreator_Operation::RemovePoints:
327 // Construct undo for RemovePoints command.
328 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointCoords;
329 CurveCreator::Coordinates aPointsToAdd;
330 const CurveCreator::Dimension aDim = theCurve->getDimension();
331 CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
332 std::list<int> aPoints;
333 int aSectionId, aPointId;
334 for ( ; anIt != aLast; anIt++ ) {
335 aPointsToAdd.clear();
336 aSectionId = anIt->first;
337 aPointId = anIt->second;
338 const CurveCreator::Coordinates &aPoints =
339 theCurve->getPoints(aSectionId);
340 CurveCreator::Coordinates::const_iterator anIterBegin =
341 aPoints.begin() + (aDim*aPointId);
342 CurveCreator::Coordinates::const_iterator anIterEnd =
344 aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
345 aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
348 isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
349 aSectionToPointCoords);
365 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
366 const CurveCreator_Operation::Type theType,
367 const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
371 if (theCurve != NULL) {
375 myPRedo = new CurveCreator_Operation;
377 if (myPRedo->init(theType, theParamList1)) {
378 // Construct undo for different commands.
380 case CurveCreator_Operation::InsertPoints:
382 // Construct undo for RemovePoints command.
383 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
384 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
385 for ( ; anIt != aLast; anIt++ ) {
386 aSectionToPointList.push_back(anIt->first);
389 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
390 aSectionToPointList);
393 case CurveCreator_Operation::SetCoordinates:
395 // Construct undo for SetCoordinates command.
396 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
397 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
398 for ( ; anIt != aLast; anIt++ ) {
399 CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
400 aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
404 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
405 aSectionToPointOldCoords);
421 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
422 const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
426 if (theCurve != NULL && theOldParamList.size() > 0) {
430 myPRedo = new CurveCreator_Operation;
432 // Construct redo for SetCoordinates command.
433 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointActualCoords;
434 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt =
435 theOldParamList.begin(), aLast = theOldParamList.end();
436 for ( ; anIt != aLast; anIt++ ) {
437 CurveCreator::Coordinates anActualCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
438 aSectionToPointActualCoords.push_back(std::make_pair(anIt->first, anActualCoords));
441 if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
442 // Undo for SetCoordinates command.
444 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
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);