Salome HOME
refs #249 - Undo after Join selected sections operation works not properly
[modules/hydro.git] / src / HYDROCurveCreator / CurveCreator_Operation.cxx
1 // Copyright (C) 2013  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.
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_Operation.cxx
21 // Author:      Sergey KHROMOV
22
23 #include "CurveCreator_Operation.hxx"
24 #include "CurveCreator_Curve.hxx"
25 #include "CurveCreator.hxx"
26
27 #include <string>
28 #include <stdlib.h>
29 #include <string.h>
30
31 //=======================================================================
32 // function: Constructor
33 // purpose:
34 //=======================================================================
35 CurveCreator_Operation::CurveCreator_Operation()
36 : myType  (CurveCreator_Operation::Unknown),
37   myPData (NULL)
38 {
39 }
40
41 //=======================================================================
42 // function: Destructor
43 // purpose:
44 //=======================================================================
45 CurveCreator_Operation::~CurveCreator_Operation()
46 {
47   clear();
48 }
49
50 bool compId(CurveCreator_PosPoint* p1, CurveCreator_PosPoint* p2)
51 {
52   return p1->myID < p2->myID;
53 }
54
55 //=======================================================================
56 // function: Constructor
57 // purpose:
58 //=======================================================================
59 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType)
60 {
61   bool isOK = false;
62
63   if (theType == CurveCreator_Operation::Clear) {
64     clear();
65     myType = theType;
66     isOK   = true;
67   }
68
69   return isOK;
70 }
71
72 //=======================================================================
73 // function: Constructor
74 // purpose:
75 //=======================================================================
76 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
77                                   const int theIntParam)
78 {
79   bool isOK = false;
80
81   if (theType == CurveCreator_Operation::RemoveSection) {
82     int *pData = (int *)allocate(sizeof(int));
83
84     pData[0] = theIntParam;
85     myType   = theType;
86     isOK     = true;
87   }
88
89   return isOK;
90 }
91
92 //=======================================================================
93 // function: Constructor
94 // purpose:
95 //=======================================================================
96 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
97                                   const int theIntParam1,
98                                   const int theIntParam2)
99 {
100   bool isOK = false;
101
102   if (theType == CurveCreator_Operation::SetType     ||
103       theType == CurveCreator_Operation::SetClosed   ||
104       theType == CurveCreator_Operation::MoveSection ||
105       theType == CurveCreator_Operation::Join) {
106     int *pData = (int *)allocate(2*sizeof(int));
107
108     pData[0] = theIntParam1;
109     pData[1] = theIntParam2;
110     myType   = theType;
111     isOK     = true;
112   }
113
114   return isOK;
115 }
116
117 //=======================================================================
118 // function: Constructor
119 // purpose:
120 //=======================================================================
121 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
122                                   const CurveCreator::Coordinates &theCoords,
123                                   const int theIntParam)
124 {
125   bool isOK = false;
126
127   if (theType == CurveCreator_Operation::AddPoints) {
128     const int aNbCoords = theCoords.size();
129     const size_t aSize =
130       2*sizeof(theIntParam) + aNbCoords*sizeof(CurveCreator::TypeCoord);
131     int *pIntData = (int *)allocate(aSize);
132
133     *pIntData++ = theIntParam;
134     *pIntData++ = aNbCoords;
135
136     CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)pIntData;
137     int i = 0;
138
139     for (; i < aNbCoords; i++) {
140       *pRealData++ = theCoords[i];
141     }
142
143     myType = theType;
144     isOK   = true;
145   }
146
147   return isOK;
148 }
149
150 //=======================================================================
151 // function: Constructor
152 // purpose:
153 //=======================================================================
154 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
155                                   const std::string& theName,
156                                   const CurveCreator::Coordinates &theCoords,
157                                   const int theIntParam1,
158                                   const int theIntParam2)
159 {
160   bool isOK = false;
161   if (theType == CurveCreator_Operation::AddSection ) {
162     const int aNbCoords = theCoords.size();
163     const size_t aSize =
164       3*sizeof(theIntParam1) + aNbCoords*sizeof(CurveCreator::TypeCoord) + theName.length() + 1;
165     int *pIntData = (int *)allocate(aSize);
166
167     *pIntData++ = theIntParam1;
168     *pIntData++ = theIntParam2;
169     char* aStrPtr = (char*)pIntData;
170     if( !theName.empty() ){
171         strcpy( aStrPtr, theName.c_str() );
172         aStrPtr += theName.length();
173     }
174     else{
175         *aStrPtr = 0;
176     }
177     aStrPtr++;
178     pIntData = (int*)aStrPtr;
179     *pIntData++ = aNbCoords;
180
181     CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)pIntData;
182     int i = 0;
183
184     for (; i < aNbCoords; i++) {
185       *pRealData++ = theCoords[i];
186     }
187
188     myType = theType;
189     isOK   = true;
190   }
191
192   return isOK;
193 }
194
195 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
196                                   const std::string &theName,
197                                   const int theIntParam1 )
198 {
199     if (theType == CurveCreator_Operation::RenameSection ) {
200         size_t aSize = sizeof(theIntParam1) + theName.length() + 1;
201         int *pIntData = (int *)allocate(aSize);
202         *pIntData = theIntParam1;
203         pIntData++;
204         if( !theName.empty() ){
205             strcpy( (char*)pIntData, theName.c_str() );
206         }
207         else{
208             *((char*)pIntData) = 0;
209         }
210         myType = theType;
211         return true;
212     }
213     return false;
214 }
215
216 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
217                                   const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
218 {
219   bool isOK = false;
220
221   if (theType == CurveCreator_Operation::InsertPoints ||
222       theType == CurveCreator_Operation::SetCoordinates ) {
223
224     const int aNbPoints = theParamList1.size();
225
226     CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = 
227       theParamList1.begin();
228     const int aNbCoords = anIt->second.size();
229
230     const size_t aSize =
231       sizeof(aNbPoints) + sizeof(aNbCoords) + 
232       aNbPoints * (3*sizeof(int) + aNbCoords*sizeof(CurveCreator::TypeCoord));
233     int *pIntData = (int *)allocate(aSize);
234
235     *pIntData++ = aNbPoints;
236     *pIntData++ = aNbCoords;
237     int aSectionId, aPointId;
238     for ( ; anIt != theParamList1.end(); anIt++ ) {
239       aSectionId = anIt->first.first;
240       aPointId = anIt->first.second;
241
242       *pIntData++ = aSectionId;
243       *pIntData++ = aPointId;
244       *pIntData++ = aNbCoords;
245
246       const CurveCreator::Coordinates &aCoords = anIt->second;
247       CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)pIntData;
248       for (int i = 0; i < aNbCoords; i++) {
249         *pRealData++ = aCoords[i];
250       }
251       pIntData = (int *)pRealData;
252     }
253
254     myType = theType;
255     isOK   = true;
256   }
257
258   return isOK;
259 }
260
261 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
262                                   const CurveCreator_ICurve::SectionToPointList &theParamList1)
263 {
264   bool isOK = false;
265
266   if (theType == CurveCreator_Operation::RemovePoints) {
267     const int aNbPoints = theParamList1.size();
268
269     CurveCreator_ICurve::SectionToPointList::const_iterator anIt = 
270       theParamList1.begin();
271
272     const size_t aSize =
273       sizeof(aNbPoints) +
274       aNbPoints * (2*sizeof(int));
275     int *pIntData = (int *)allocate(aSize);
276
277     *pIntData++ = aNbPoints;
278     int aSectionId, aPointId;
279     for ( ; anIt != theParamList1.end(); anIt++ ) {
280       aSectionId = anIt->first;
281       aPointId = anIt->second;
282
283       *pIntData++ = aSectionId;
284       *pIntData++ = aPointId;
285     }
286
287     myType = theType;
288     isOK   = true;
289   }
290
291   return isOK;
292 }
293
294 //=======================================================================
295 // function: apply
296 // purpose:
297 //=======================================================================
298 void CurveCreator_Operation::apply(CurveCreator_Curve *theCurve)
299 {
300   if (theCurve != NULL) {
301     int *pInt = (int *)myPData;
302
303     switch (myType) {
304       case CurveCreator_Operation::AddPoints:
305       case CurveCreator_Operation::InsertPoints:
306       case CurveCreator_Operation::SetCoordinates:
307         {
308           int aSectionId, aPointId;
309           CurveCreator::SectionsMap aSectionsMap;
310           CurveCreator::PosPointsList aPoints;
311           CurveCreator::Coordinates aCoords;
312
313           int nbPoints = pInt[0];
314           int nbCoords = pInt[1];
315           int nbParams = 3+nbCoords;
316           for (int i = 0; i < nbPoints*nbParams; i=i+nbParams) {
317             aCoords.clear();
318             aPoints.clear();
319             getCoords(&pInt[4+i], aCoords);
320             aSectionId = pInt[2+i];
321             aPointId = pInt[3+i];
322             if ( aSectionsMap.find( aSectionId ) != aSectionsMap.end() )
323               aPoints = aSectionsMap[aSectionId];
324             CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( aPointId, aCoords );
325             aPoints.push_back( aPosPoint );
326             aPoints.sort(compId);
327             aSectionsMap[aSectionId] = aPoints;
328           }
329           switch (myType) {
330             case CurveCreator_Operation::AddPoints:
331             case CurveCreator_Operation::InsertPoints:
332               theCurve->addPointsInternal( aSectionsMap );
333               break;
334             case CurveCreator_Operation::SetCoordinates:
335               theCurve->setPointInternal( aSectionsMap );
336               break;
337           }
338         }
339         break;
340       case CurveCreator_Operation::RemovePoints:
341         {
342           CurveCreator_ICurve::SectionToPointList aListOfSectionsToPoints;
343           int nbPoints = pInt[0];
344           for (int i = 1; i < nbPoints*2; i=i+2) {
345             aListOfSectionsToPoints.push_back(std::make_pair(pInt[i], pInt[i+1]));
346           }
347           theCurve->removePointsInternal(aListOfSectionsToPoints);
348         }
349         break;
350       case CurveCreator_Operation::SetType:
351         {
352           const CurveCreator::SectionType aType = (CurveCreator::SectionType) pInt[0];
353
354           theCurve->setSectionTypeInternal( pInt[1], aType );
355         }
356         break;
357       case CurveCreator_Operation::Clear:
358         theCurve->clearInternal();
359         break;
360       case CurveCreator_Operation::SetClosed:
361         theCurve->setClosedInternal(pInt[1], (pInt[0] != 0));
362         break;
363       case CurveCreator_Operation::MoveSection:
364         theCurve->moveSectionInternal(pInt[0], pInt[1]);
365         break;
366       case CurveCreator_Operation::Join:
367         if (myPData == NULL) {
368           theCurve->joinInternal();
369         } else {
370           theCurve->joinInternal(pInt[0], pInt[1]);
371         }
372         break;
373       case CurveCreator_Operation::AddSection:
374         {
375           const CurveCreator::SectionType aType = (CurveCreator::SectionType) pInt[0];
376
377           std::string aName = std::string((char*)&pInt[2]);
378
379           CurveCreator::Coordinates aCoords;
380
381           char* aPtr =  ((char*)&pInt[2]);
382           aPtr += (aName.length()) + 1;
383           getCoords((int*)aPtr, aCoords);
384           theCurve->addSectionInternal(aName, aType, (pInt[1] != 0), aCoords);
385         }
386         break;
387       case CurveCreator_Operation::RemoveSection:
388         theCurve->removeSectionInternal(pInt[0]);
389         break;
390       case CurveCreator_Operation::RenameSection:
391         {
392             std::string aName = std::string((char*)&pInt[1]);
393             theCurve->setSectionNameInternal(pInt[0], aName);
394         }
395         break;
396       default:
397         break;
398     }
399   }
400 }
401
402 //=======================================================================
403 // function: allocate
404 // purpose:
405 //=======================================================================
406 void *CurveCreator_Operation::allocate(const size_t theSize)
407 {
408   if (myPData != NULL) {
409     clear();
410   }
411
412   myPData = malloc(theSize);
413
414   return myPData;
415 }
416
417 //=======================================================================
418 // function: clear
419 // purpose:
420 //=======================================================================
421 void CurveCreator_Operation::clear()
422 {
423   myType = CurveCreator_Operation::Unknown;
424
425   if (myPData != NULL) {
426     free(myPData);
427     myPData = NULL;
428   }
429 }
430
431 //=======================================================================
432 // function: getCoords
433 // purpose:
434 //=======================================================================
435 void CurveCreator_Operation::getCoords
436           (int *thePInt, CurveCreator::Coordinates &theCoords) const
437 {
438   const int aNbPnts = *thePInt;
439   CurveCreator::TypeCoord *pCoord = (CurveCreator::TypeCoord *)&thePInt[1];
440
441   for (int i = 0; i < aNbPnts; i++) {
442     theCoords.push_back(pCoord[i]);
443   }
444 }