1 // Copyright (C) 2013-2020 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, or (at your option) any later version.
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 required: 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);
288 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
289 const CurveCreator_Operation::Type theType,
290 const std::string &theName,
291 const int theIntParam1 )
294 myPRedo = new CurveCreator_Operation;
296 if (myPRedo->init(theType, theName, theIntParam1 )) {
297 // Construct undo for different commands.
299 case CurveCreator_Operation::RenameSection:
301 isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
302 theCurve->getSectionName(theIntParam1), theIntParam1);
314 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
315 const CurveCreator_Operation::Type theType,
316 const CurveCreator_ICurve::SectionToPointList &theParamList1)
320 if (theCurve != NULL) {
324 myPRedo = new CurveCreator_Operation;
326 if (myPRedo->init(theType, theParamList1)) {
327 // Construct undo for different commands.
329 case CurveCreator_Operation::RemovePoints:
331 // Construct undo for RemovePoints command.
332 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointCoords;
333 CurveCreator::Coordinates aPointsToAdd;
334 const CurveCreator::Dimension aDim = theCurve->getDimension();
335 CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
336 std::list<int> aPoints;
337 int aSectionId, aPointId;
338 for ( ; anIt != aLast; anIt++ ) {
339 aPointsToAdd.clear();
340 aSectionId = anIt->first;
341 aPointId = anIt->second;
342 const CurveCreator::Coordinates &aPoints =
343 theCurve->getCoords(aSectionId);
344 CurveCreator::Coordinates::const_iterator anIterBegin =
345 aPoints.begin() + (aDim*aPointId);
346 CurveCreator::Coordinates::const_iterator anIterEnd =
348 aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
349 aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
352 isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
353 aSectionToPointCoords);
369 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
370 const CurveCreator_Operation::Type theType,
371 const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
375 if (theCurve != NULL) {
379 myPRedo = new CurveCreator_Operation;
381 if (myPRedo->init(theType, theParamList1)) {
382 // Construct undo for different commands.
384 case CurveCreator_Operation::InsertPoints:
386 // Construct undo for RemovePoints command.
387 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
388 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
389 for ( ; anIt != aLast; anIt++ ) {
390 aSectionToPointList.push_back(anIt->first);
393 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
394 aSectionToPointList);
397 case CurveCreator_Operation::SetCoordinates:
399 // Construct undo for SetCoordinates command.
400 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
401 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
402 for ( ; anIt != aLast; anIt++ ) {
403 CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
404 aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
408 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
409 aSectionToPointOldCoords);
425 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
426 const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
430 if (theCurve != NULL && theOldParamList.size() > 0) {
434 myPRedo = new CurveCreator_Operation;
436 // Construct redo for SetCoordinates command.
437 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointActualCoords;
438 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt =
439 theOldParamList.begin(), aLast = theOldParamList.end();
440 for ( ; anIt != aLast; anIt++ ) {
441 CurveCreator::Coordinates anActualCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
442 aSectionToPointActualCoords.push_back(std::make_pair(anIt->first, anActualCoords));
445 if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
446 // Undo for SetCoordinates command.
448 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
460 //=======================================================================
461 // function: applyUndo
463 //=======================================================================
464 void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
466 if (myNbUndos > 0 && myPUndo != NULL) {
467 for (int i = 0; i < myNbUndos; i++) {
468 myPUndo[i].apply(theCurve);
473 //=======================================================================
474 // function: applyRedo
476 //=======================================================================
477 void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
479 if (myPRedo != NULL) {
480 myPRedo->apply(theCurve);
484 //=======================================================================
487 //=======================================================================
488 void CurveCreator_Diff::clear()
490 if (myPUndo != NULL) {
497 if (myPRedo != NULL) {
503 //=======================================================================
504 // function: setNbUndos
506 //=======================================================================
507 void CurveCreator_Diff::setNbUndos(const int theNbUndos)
509 myNbUndos = theNbUndos;
510 myPUndo = new CurveCreator_Operation[myNbUndos];
513 //=======================================================================
514 // function: getSectionIndex
516 //=======================================================================
517 int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
518 const int theIndex) const
520 return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
523 //=======================================================================
524 // function: addSectionToUndo
526 //=======================================================================
527 bool CurveCreator_Diff::addSectionToUndo
528 (const CurveCreator_Curve *theCurve,
530 CurveCreator_Operation &theOperation) const
532 const std::string aName = theCurve->getSectionName(theIndex);
533 const CurveCreator::Coordinates &aPnts = theCurve->getCoords(theIndex);
534 const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
535 const bool isClosed = theCurve->isClosed(theIndex);
537 bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
538 aName, aPnts, aType, isClosed);
543 //=======================================================================
544 // function: setTypeOrClosedToUndo
546 //=======================================================================
547 bool CurveCreator_Diff::setTypeOrClosedToUndo
548 (const CurveCreator_Curve *theCurve,
549 const CurveCreator_Operation::Type theType,
550 const int theIntParam1,
551 const int theIntParam2)
555 // Compute number of modified sections.
556 const bool isSetType = (theType == CurveCreator_Operation::SetType);
558 std::list<int> aListOfInd;
562 if (theIntParam2 == -1) {
563 // The operation is applied to all sections. We need to collect
564 // really modified sections for undo.
565 const int aNbSections = theCurve->getNbSections();
567 if (aNbSections > 0) {
568 // Get sections to be modified.
569 for (i = 0; i < aNbSections; i++) {
571 aValue = theCurve->getSectionType(i);
573 aValue = theCurve->isClosed(i);
576 if (theIntParam1 != aValue) {
578 aListOfInd.push_back(i);
582 if (aNbSections == aNbModif) {
583 // All sections are modified. We can use one single command
584 // with -1 section index.
587 aListOfInd.push_back(-1);
591 // There is only particular section modified.
592 // Check if there is a real modification required.
594 aValue = theCurve->getSectionType(theIntParam2);
596 aValue = theCurve->isClosed(theIntParam2);
599 if (theIntParam1 != aValue) {
601 aListOfInd.push_back(theIntParam2);
607 std::list<int>::iterator anIter = aListOfInd.begin();
610 aValue = theCurve->getSectionType(*anIter);
612 aValue = theCurve->isClosed(*anIter);
615 setNbUndos(aNbModif);
617 for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
618 isOK = myPUndo[i].init(theType, aValue, *anIter);