1 // Copyright (C) 2013-2022 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"
25 #include "CurveCreator_Section.hxx"
26 #include "CurveCreator_Utils.hxx"
30 //=======================================================================
31 // function: Constructor
33 //=======================================================================
34 CurveCreator_Diff::CurveCreator_Diff()
41 //=======================================================================
42 // function: Destructor
44 //=======================================================================
45 CurveCreator_Diff::~CurveCreator_Diff()
50 //=======================================================================
53 //=======================================================================
54 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve)
56 CurveCreator_Operation::Type aType = CurveCreator_Operation::Clear;
59 if (theCurve != NULL) {
63 myPRedo = new CurveCreator_Operation;
65 if (myPRedo->init(aType)) {
68 const int aNbSections = theCurve->getNbSections();
70 // Construct undo for Clear command.
71 if (aNbSections > 0) {
72 setNbUndos(aNbSections);
74 for (int i = 0; i < aNbSections && isOK; i++) {
75 // Add AddSection command.
76 isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
89 //=======================================================================
92 //=======================================================================
93 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
94 const CurveCreator_Operation::Type theType,
95 const int theIntParam)
99 if (theCurve != NULL) {
103 myPRedo = new CurveCreator_Operation;
105 if (myPRedo->init(theType, theIntParam)) {
106 // Construct undo for RemoveSection command.
107 // If the last section is removed, one AddSection command is enough.
108 // If not last section is removed, two commands are required: AddSection
110 const int aLastIndex = theCurve->getNbSections() - 1;
112 if (theIntParam == aLastIndex) {
118 isOK = addSectionToUndo(theCurve, theIntParam, myPUndo[0]);
120 if (isOK && theIntParam != aLastIndex) {
121 isOK = myPUndo[1].init(CurveCreator_Operation::MoveSection,
122 aLastIndex, theIntParam);
134 //=======================================================================
137 //=======================================================================
138 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
139 const CurveCreator_Operation::Type theType,
140 const int theIntParam1,
141 const int theIntParam2)
145 if (theCurve != NULL) {
149 myPRedo = new CurveCreator_Operation;
151 if (myPRedo->init(theType, theIntParam1, theIntParam2)) {
152 // Construct undo for different commands.
154 case CurveCreator_Operation::SetType:
155 case CurveCreator_Operation::SetClosed:
156 isOK = setTypeOrClosedToUndo
157 (theCurve, theType, theIntParam1, theIntParam2);
159 case CurveCreator_Operation::MoveSection:
161 isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
176 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
177 const CurveCreator_Operation::Type theType,
178 const int theIntParam1,
179 const int theIntParam2[3])
183 if (theCurve != NULL)
186 myPRedo = new CurveCreator_Operation;
188 if (myPRedo->init(theType, theIntParam1, theIntParam2))
190 Quantity_Color aColor = theCurve->getColorSection(theIntParam1);
193 QColor aQColor = CurveCreator_Utils::colorConv(aColor);
194 int colorArr[3] = {aQColor.red(),aQColor.green(), aQColor.blue()};
196 isOK = myPUndo[0].init(theType, theIntParam1, colorArr);
206 //=======================================================================
209 //=======================================================================
210 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
211 const CurveCreator_Operation::Type theType,
212 const std::list<int>& theParams)
216 if (theCurve != NULL || theParams.empty()) {
220 myPRedo = new CurveCreator_Operation;
222 if (myPRedo->init(theType, theParams)) {
223 // Construct undo for different commands.
225 case CurveCreator_Operation::Join:
227 int aSectionMain = theParams.front();
228 const int aNbPointsMain = theCurve->getNbPoints(aSectionMain);
230 std::list<int> aSectionsToJoin = theParams;
231 aSectionsToJoin.erase( aSectionsToJoin.begin() );
232 // it is important to sort the section indices in order to correct perform undo
233 // for the move sections to the previous positions
234 aSectionsToJoin.sort();
235 // 1rst undo for remove points from the main and n-1 undoes to contain joined sections
236 int aSectionsToJoinNb = aSectionsToJoin.size();
237 int aNbUndos = 2*aSectionsToJoinNb + 1;
238 setNbUndos( aNbUndos );
240 // Add joined sections to undo
241 std::list<int>::const_iterator anIt = aSectionsToJoin.begin(),
242 aLast = aSectionsToJoin.end();
243 anIt = aSectionsToJoin.begin();
244 int aLastSectionId = -1;
245 for (int i = 0; anIt != aLast && i < aSectionsToJoinNb; anIt++, i++) {
246 int anISection = *anIt;
247 isOK = addSectionToUndo( theCurve, anISection, myPUndo[i*2] );
249 isOK = myPUndo[i*2+1].init(CurveCreator_Operation::MoveSection,
250 aLastSectionId, anISection);
255 // Construct undo for RemovePoints command.
257 int aNbPointsInJoined = 0;
258 anIt = aSectionsToJoin.begin();
259 for ( ; anIt != aLast; anIt++ )
260 aNbPointsInJoined += theCurve->getNbPoints( *anIt );
262 int aJoinedSize = aNbPointsMain + aNbPointsInJoined;
263 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
264 for (int anIPoint = aNbPointsMain; anIPoint < aJoinedSize; anIPoint++)
265 aSectionToPointList.push_back(std::make_pair(aSectionMain, anIPoint));
267 isOK = myPUndo[aNbUndos-1].init(CurveCreator_Operation::RemovePoints, aSectionToPointList);
284 //=======================================================================
287 //=======================================================================
288 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
289 const CurveCreator_Operation::Type theType,
290 const std::string& theName,
291 const CurveCreator::Coordinates &theCoords,
292 const int theIntParam1,
293 const int theIntParam2)
297 if (theCurve != NULL) {
301 myPRedo = new CurveCreator_Operation;
303 if (myPRedo->init(theType, theName, theCoords, theIntParam1, theIntParam2)) {
304 // Construct undo for different commands.
306 case CurveCreator_Operation::AddSection:
308 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);
346 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
347 const CurveCreator_Operation::Type theType,
348 const CurveCreator_ICurve::SectionToPointList &theParamList1)
352 if (theCurve != NULL) {
356 myPRedo = new CurveCreator_Operation;
358 if (myPRedo->init(theType, theParamList1)) {
359 // Construct undo for different commands.
361 case CurveCreator_Operation::RemovePoints:
363 // Construct undo for RemovePoints command.
364 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointCoords;
365 CurveCreator::Coordinates aPointsToAdd;
366 const CurveCreator::Dimension aDim = theCurve->getDimension();
367 CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
368 std::list<int> aPoints;
369 int aSectionId, aPointId;
370 for ( ; anIt != aLast; anIt++ ) {
371 aPointsToAdd.clear();
372 aSectionId = anIt->first;
373 aPointId = anIt->second;
374 const CurveCreator::Coordinates &aPoints =
375 theCurve->getCoords(aSectionId);
376 CurveCreator::Coordinates::const_iterator anIterBegin =
377 aPoints.begin() + (aDim*aPointId);
378 CurveCreator::Coordinates::const_iterator anIterEnd =
380 aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
381 aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
384 isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
385 aSectionToPointCoords);
401 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
402 const CurveCreator_Operation::Type theType,
403 const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
407 if (theCurve != NULL) {
411 myPRedo = new CurveCreator_Operation;
413 if (myPRedo->init(theType, theParamList1)) {
414 // Construct undo for different commands.
416 case CurveCreator_Operation::InsertPoints:
418 // Construct undo for RemovePoints command.
419 CurveCreator_ICurve::SectionToPointList aSectionToPointList;
420 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
421 for ( ; anIt != aLast; anIt++ ) {
422 aSectionToPointList.push_back(anIt->first);
425 isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
426 aSectionToPointList);
429 case CurveCreator_Operation::SetCoordinates:
431 // Construct undo for SetCoordinates command.
432 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
433 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
434 for ( ; anIt != aLast; anIt++ ) {
435 CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
436 aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
440 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
441 aSectionToPointOldCoords);
457 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
458 const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
462 if (theCurve != NULL && theOldParamList.size() > 0) {
466 myPRedo = new CurveCreator_Operation;
468 // Construct redo for SetCoordinates command.
469 CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointActualCoords;
470 CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt =
471 theOldParamList.begin(), aLast = theOldParamList.end();
472 for ( ; anIt != aLast; anIt++ ) {
473 CurveCreator::Coordinates anActualCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
474 aSectionToPointActualCoords.push_back(std::make_pair(anIt->first, anActualCoords));
477 if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
478 // Undo for SetCoordinates command.
480 isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
492 //=======================================================================
493 // function: applyUndo
495 //=======================================================================
496 void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
498 if (myNbUndos > 0 && myPUndo != NULL) {
499 for (int i = 0; i < myNbUndos; i++) {
500 myPUndo[i].apply(theCurve);
505 //=======================================================================
506 // function: applyRedo
508 //=======================================================================
509 void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
511 if (myPRedo != NULL) {
512 myPRedo->apply(theCurve);
516 //=======================================================================
519 //=======================================================================
520 void CurveCreator_Diff::clear()
522 if (myPUndo != NULL) {
529 if (myPRedo != NULL) {
535 //=======================================================================
536 // function: setNbUndos
538 //=======================================================================
539 void CurveCreator_Diff::setNbUndos(const int theNbUndos)
541 myNbUndos = theNbUndos;
542 myPUndo = new CurveCreator_Operation[myNbUndos];
545 //=======================================================================
546 // function: getSectionIndex
548 //=======================================================================
549 int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
550 const int theIndex) const
552 return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
555 //=======================================================================
556 // function: addSectionToUndo
558 //=======================================================================
559 bool CurveCreator_Diff::addSectionToUndo
560 (const CurveCreator_Curve *theCurve,
562 CurveCreator_Operation &theOperation) const
564 const std::string aName = theCurve->getSectionName(theIndex);
565 const CurveCreator::Coordinates &aPnts = theCurve->getCoords(theIndex);
566 const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
567 const bool isClosed = theCurve->isClosed(theIndex);
569 bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
570 aName, aPnts, aType, isClosed);
575 //=======================================================================
576 // function: setTypeOrClosedToUndo
578 //=======================================================================
579 bool CurveCreator_Diff::setTypeOrClosedToUndo
580 (const CurveCreator_Curve *theCurve,
581 const CurveCreator_Operation::Type theType,
582 const int theIntParam1,
583 const int theIntParam2)
587 // Compute number of modified sections.
588 const bool isSetType = (theType == CurveCreator_Operation::SetType);
590 std::list<int> aListOfInd;
594 if (theIntParam2 == -1) {
595 // The operation is applied to all sections. We need to collect
596 // really modified sections for undo.
597 const int aNbSections = theCurve->getNbSections();
599 if (aNbSections > 0) {
600 // Get sections to be modified.
601 for (i = 0; i < aNbSections; i++) {
603 aValue = theCurve->getSectionType(i);
605 aValue = theCurve->isClosed(i);
608 if (theIntParam1 != aValue) {
610 aListOfInd.push_back(i);
614 if (aNbSections == aNbModif) {
615 // All sections are modified. We can use one single command
616 // with -1 section index.
619 aListOfInd.push_back(-1);
623 // There is only particular section modified.
624 // Check if there is a real modification required.
626 aValue = theCurve->getSectionType(theIntParam2);
628 aValue = theCurve->isClosed(theIntParam2);
631 if (theIntParam1 != aValue) {
633 aListOfInd.push_back(theIntParam2);
639 std::list<int>::iterator anIter = aListOfInd.begin();
642 aValue = theCurve->getSectionType(*anIter);
644 aValue = theCurve->isClosed(*anIter);
647 setNbUndos(aNbModif);
649 for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
650 isOK = myPUndo[i].init(theType, aValue, *anIter);