]> SALOME platform Git repositories - modules/geom.git/blob - src/CurveCreator/CurveCreator_Diff.cxx
Salome HOME
#18963 Minimize compiler warnings
[modules/geom.git] / src / CurveCreator / CurveCreator_Diff.cxx
1 // Copyright (C) 2013-2020  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File:        CurveCreator_Diff.cxx
21 // Author:      Sergey KHROMOV
22
23 #include "CurveCreator_Diff.hxx"
24 #include "CurveCreator_Curve.hxx"
25
26 #include <list>
27
28 //=======================================================================
29 // function: Constructor
30 // purpose:
31 //=======================================================================
32 CurveCreator_Diff::CurveCreator_Diff()
33 : myNbUndos (0),
34   myPUndo   (NULL),
35   myPRedo   (NULL)
36 {
37 }
38
39 //=======================================================================
40 // function: Destructor
41 // purpose:
42 //=======================================================================
43 CurveCreator_Diff::~CurveCreator_Diff()
44 {
45   clear();
46 }
47
48 //=======================================================================
49 // function: init
50 // purpose:
51 //=======================================================================
52 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve)
53 {
54   CurveCreator_Operation::Type aType = CurveCreator_Operation::Clear;
55   bool isOK = false;
56
57   if (theCurve != NULL) {
58     clear();
59
60     // Set redo.
61     myPRedo = new CurveCreator_Operation;
62
63     if (myPRedo->init(aType)) {
64       isOK = true;
65
66       const int aNbSections = theCurve->getNbSections();
67
68       // Construct undo for Clear command.
69       if (aNbSections > 0) {
70         setNbUndos(aNbSections);
71
72         for (int i = 0; i < aNbSections && isOK; i++) {
73           // Add AddSection command.
74           isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
75         }
76       }
77     }
78
79     if (!isOK) {
80       clear();
81     }
82   }
83
84   return isOK;
85 }
86
87 //=======================================================================
88 // function: init
89 // purpose:
90 //=======================================================================
91 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
92                              const CurveCreator_Operation::Type theType,
93                              const int theIntParam)
94 {
95   bool isOK = false;
96
97   if (theCurve != NULL) {
98     clear();
99
100     // Set redo.
101     myPRedo = new CurveCreator_Operation;
102
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
107       // and MoveSection.
108       const int aLastIndex = theCurve->getNbSections() - 1;
109
110       if (theIntParam == aLastIndex) {
111         setNbUndos(1);
112       } else {
113         setNbUndos(2);
114       }
115
116       isOK = addSectionToUndo(theCurve, theIntParam, myPUndo[0]);
117
118       if (isOK && theIntParam != aLastIndex) {
119         isOK = myPUndo[1].init(CurveCreator_Operation::MoveSection,
120                                aLastIndex, theIntParam);
121       }
122     }
123
124     if (!isOK) {
125       clear();
126     }
127   }
128
129   return isOK;
130 }
131
132 //=======================================================================
133 // function: init
134 // purpose:
135 //=======================================================================
136 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
137                              const CurveCreator_Operation::Type theType,
138                              const int theIntParam1,
139                              const int theIntParam2)
140 {
141   bool isOK = false;
142
143   if (theCurve != NULL) {
144     clear();
145
146     // Set redo.
147     myPRedo = new CurveCreator_Operation;
148
149     if (myPRedo->init(theType, theIntParam1, theIntParam2)) {
150       // Construct undo for different commands.
151       switch (theType) {
152         case CurveCreator_Operation::SetType:
153         case CurveCreator_Operation::SetClosed:
154             isOK = setTypeOrClosedToUndo
155               (theCurve, theType, theIntParam1, theIntParam2);
156           break;
157         case CurveCreator_Operation::MoveSection:
158           setNbUndos(1);
159           isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
160           break;
161         default:
162           break;
163       }
164     }
165
166     if (!isOK) {
167       clear();
168     }
169   }
170
171   return isOK;
172 }
173
174 //=======================================================================
175 // function: init
176 // purpose:
177 //=======================================================================
178 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
179                              const CurveCreator_Operation::Type theType,
180                              const std::list<int>& theParams)
181 {
182   bool isOK = false;
183
184   if (theCurve != NULL || theParams.empty()) {
185     clear();
186
187     // Set redo.
188     myPRedo = new CurveCreator_Operation;
189
190     if (myPRedo->init(theType, theParams)) {
191       // Construct undo for different commands.
192       switch (theType) {
193         case CurveCreator_Operation::Join:
194           {
195             int aSectionMain = theParams.front();
196             const int aNbPointsMain  = theCurve->getNbPoints(aSectionMain);
197
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 );
207
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] );
216               if (isOK) {
217                 isOK = myPUndo[i*2+1].init(CurveCreator_Operation::MoveSection,
218                                            aLastSectionId, anISection);
219                 if (!isOK)
220                   break;
221               }
222             }
223             // Construct undo for RemovePoints command.
224             if (isOK) {
225               int aNbPointsInJoined = 0;
226               anIt = aSectionsToJoin.begin();
227               for ( ; anIt != aLast; anIt++ )
228                 aNbPointsInJoined += theCurve->getNbPoints( *anIt );
229
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));
234
235               isOK = myPUndo[aNbUndos-1].init(CurveCreator_Operation::RemovePoints, aSectionToPointList);
236             }
237           }
238           break;
239         default:
240           break;
241       }
242     }
243
244     if (!isOK) {
245       clear();
246     }
247   }
248
249   return isOK;
250 }
251
252 //=======================================================================
253 // function: init
254 // purpose:
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)
262 {
263     bool isOK = false;
264
265     if (theCurve != NULL) {
266       clear();
267
268       // Set redo.
269       myPRedo = new CurveCreator_Operation;
270
271       if (myPRedo->init(theType, theName, theCoords, theIntParam1, theIntParam2)) {
272         // Construct undo for different commands.
273         switch (theType) {
274           case CurveCreator_Operation::AddSection:
275             setNbUndos(1);
276             isOK = myPUndo[0].init(CurveCreator_Operation::RemoveSection, -1);
277             break;
278         default:
279           break;
280         }
281       }
282     }
283     if( !isOK )
284         clear();
285     return isOK;
286 }
287
288 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
289                              const CurveCreator_Operation::Type theType,
290                              const std::string &theName,
291                              const int theIntParam1 )
292 {
293   bool isOK = false;
294   myPRedo = new CurveCreator_Operation;
295
296   if (myPRedo->init(theType, theName, theIntParam1 )) {
297     // Construct undo for different commands.
298     switch (theType) {
299       case CurveCreator_Operation::RenameSection:
300         setNbUndos(1);
301         isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
302                                theCurve->getSectionName(theIntParam1), theIntParam1);
303         break;
304       default:
305         break;
306     }
307   }
308   if( !isOK ){
309     clear();
310   }
311   return isOK;
312 }
313
314 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
315                              const CurveCreator_Operation::Type theType,
316                              const CurveCreator_ICurve::SectionToPointList &theParamList1)
317 {
318   bool isOK = false;
319
320   if (theCurve != NULL) {
321     clear();
322
323     // Set redo.
324     myPRedo = new CurveCreator_Operation;
325
326     if (myPRedo->init(theType, theParamList1)) {
327       // Construct undo for different commands.
328       switch (theType) {
329         case CurveCreator_Operation::RemovePoints:
330           {
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 = 
347                 anIterBegin + aDim;
348               aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
349               aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
350             }
351             setNbUndos(1);
352             isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
353                                    aSectionToPointCoords);
354           }
355           break;
356         default:
357           break;
358       }
359     }
360
361     if (!isOK) {
362       clear();
363     }
364   }
365
366   return isOK;
367 }
368
369 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
370                              const CurveCreator_Operation::Type theType,
371                              const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
372 {
373   bool isOK = false;
374
375   if (theCurve != NULL) {
376     clear();
377
378     // Set redo.
379     myPRedo = new CurveCreator_Operation;
380
381     if (myPRedo->init(theType, theParamList1)) {
382       // Construct undo for different commands.
383       switch (theType) {
384         case CurveCreator_Operation::InsertPoints:
385           {
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);
391             }
392             setNbUndos(1);
393             isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
394                                    aSectionToPointList);
395           }
396           break;
397         case CurveCreator_Operation::SetCoordinates:
398           {
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));
405             }
406
407             setNbUndos(1);
408             isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
409                                    aSectionToPointOldCoords);
410           }
411           break;
412         default:
413           break;
414       }
415     }
416
417     if (!isOK) {
418       clear();
419     }
420   }
421
422   return isOK;
423 }
424
425 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
426                              const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
427 {
428   bool isOK = false;
429
430   if (theCurve != NULL && theOldParamList.size() > 0) {
431     clear();
432
433     // Set redo.
434     myPRedo = new CurveCreator_Operation;
435
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));
443     }
444
445     if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
446       // Undo for SetCoordinates command.
447       setNbUndos(1);
448       isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
449                              theOldParamList);
450     }
451
452     if (!isOK) {
453       clear();
454     }
455   }
456
457   return isOK;
458 }
459
460 //=======================================================================
461 // function: applyUndo
462 // purpose:
463 //=======================================================================
464 void CurveCreator_Diff::applyUndo(CurveCreator_Curve *theCurve)
465 {
466   if (myNbUndos > 0 && myPUndo != NULL) {
467     for (int i = 0; i < myNbUndos; i++) {
468       myPUndo[i].apply(theCurve);
469     }
470   }
471 }
472
473 //=======================================================================
474 // function: applyRedo
475 // purpose:
476 //=======================================================================
477 void CurveCreator_Diff::applyRedo(CurveCreator_Curve *theCurve)
478 {
479   if (myPRedo != NULL) {
480     myPRedo->apply(theCurve);
481   }
482 }
483
484 //=======================================================================
485 // function: clear
486 // purpose:
487 //=======================================================================
488 void CurveCreator_Diff::clear()
489 {
490   if (myPUndo != NULL) {
491     delete [] myPUndo;
492     myPUndo = NULL;
493   }
494
495   myNbUndos = 0;
496
497   if (myPRedo != NULL) {
498     delete myPRedo;
499     myPRedo = NULL;
500   }
501 }
502
503 //=======================================================================
504 // function: setNbUndos
505 // purpose:
506 //=======================================================================
507 void CurveCreator_Diff::setNbUndos(const int theNbUndos)
508 {
509   myNbUndos = theNbUndos;
510   myPUndo = new CurveCreator_Operation[myNbUndos];
511 }
512
513 //=======================================================================
514 // function: getSectionIndex
515 // purpose:
516 //=======================================================================
517 int CurveCreator_Diff::getSectionIndex(const CurveCreator_Curve *theCurve,
518                                        const int theIndex) const
519 {
520   return (theIndex == -1 ? theCurve->getNbSections() - 1 : theIndex);
521 }
522
523 //=======================================================================
524 // function: addSectionToUndo
525 // purpose:
526 //=======================================================================
527 bool CurveCreator_Diff::addSectionToUndo
528                       (const CurveCreator_Curve *theCurve,
529                        const int theIndex,
530                        CurveCreator_Operation &theOperation) const
531 {
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);
536
537   bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
538                                 aName, aPnts, aType, isClosed);
539
540   return isOK;
541 }
542
543 //=======================================================================
544 // function: setTypeOrClosedToUndo
545 // purpose:
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)
552 {
553   bool isOK = true;
554
555   // Compute number of modified sections.
556   const bool isSetType = (theType == CurveCreator_Operation::SetType);
557   int aNbModif = 0;
558   std::list<int> aListOfInd;
559   int aValue;
560   int i;
561
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();
566
567     if (aNbSections > 0) {
568       // Get sections to be modified.
569       for (i = 0; i < aNbSections; i++) {
570         if (isSetType) {
571           aValue = theCurve->getSectionType(i);
572         } else {
573           aValue = theCurve->isClosed(i);
574         }
575
576         if (theIntParam1 != aValue) {
577           aNbModif++;
578           aListOfInd.push_back(i);
579         }
580       }
581
582       if (aNbSections == aNbModif) {
583         // All sections are modified. We can use one single command
584         // with -1 section index.
585         aNbModif = 1;
586         aListOfInd.clear();
587         aListOfInd.push_back(-1);
588       }
589     }
590   } else {
591     // There is only particular section modified.
592     // Check if there is a real modification required.
593     if (isSetType) {
594       aValue = theCurve->getSectionType(theIntParam2);
595     } else {
596       aValue = theCurve->isClosed(theIntParam2);
597     }
598
599     if (theIntParam1 != aValue) {
600       aNbModif = 1;
601       aListOfInd.push_back(theIntParam2);
602     }
603   }
604
605   if (aNbModif > 0) {
606     // Store the undos
607     std::list<int>::iterator anIter = aListOfInd.begin();
608
609     if (isSetType) {
610       aValue = theCurve->getSectionType(*anIter);
611     } else {
612       aValue = theCurve->isClosed(*anIter);
613     }
614
615     setNbUndos(aNbModif);
616
617     for (i = 0; anIter != aListOfInd.end() && isOK; i++, anIter++) {
618       isOK = myPUndo[i].init(theType, aValue, *anIter);
619     }
620   }
621
622   return isOK;
623 }