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