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