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