]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_SinusX.cxx
Salome HOME
4e9368525f26778ee220812792fad125371a4097
[modules/hydro.git] / src / HYDROData / HYDROData_SinusX.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROData_SinusX.h"
20
21 #include <HYDROData_PolylineXY.h>
22 #include <HYDROData_Bathymetry.h>
23 #include <HYDROData_Entity.h>
24 #include <HYDROData_Document.h>
25 #include <HYDROData_Profile.h>
26 #include <HYDROData_Iterator.h>
27
28 #include <gp_XYZ.hxx>
29 #include <gp_XY.hxx>
30
31 #include <QFile>
32 #include <QFileInfo>
33 #include <QString>
34 #include <QStringList>
35 #include <QTextStream>
36 #include <QColor>
37
38 HYDROData_SinusX::HYDROData_SinusX( ) 
39 {
40 }
41
42 HYDROData_SinusX::~HYDROData_SinusX()
43 {
44 }
45
46 void HYDROData_SinusX::CollectExistingNames(Handle(HYDROData_Document) theDocument)
47 {
48   HYDROData_Iterator anIter( theDocument );
49   int anInd = 0;
50   myExistingNames.clear();
51   std::vector<int> anAllowedIndexes;
52   for( ; anIter.More(); anIter.Next() )
53     myExistingNames.push_back(anIter.Current()->GetName());
54 }
55
56 QString HYDROData_SinusX::GetName(const QString& theName)
57 {
58   if (myExistingNames.contains(theName))
59   { 
60     QString aName = theName; 
61     while (myExistingNames.contains(aName)) 
62     {
63       QStringList aList = aName.split("_");
64       int aLastInd = aName.lastIndexOf("_");
65       bool IsNum = false; 
66       int anInd = -1;
67       anInd = aList.last().toInt(&IsNum);
68       if (IsNum)
69       {
70         aName = aName.left(aLastInd) + "_";
71         aName+= QString::number(++anInd);
72       }
73       else
74         aName = theName + "_0";
75     }
76
77     myExistingNames.push_back(aName);
78     return aName;
79   }
80   else
81   {
82     myExistingNames.push_back(theName);
83     return theName;
84   }
85
86 }
87
88
89 bool HYDROData_SinusX::OpenAndParse(const QString& theFilePath)
90 {
91   if ( theFilePath.isEmpty() )
92   { 
93     return false;
94   }
95
96   QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
97
98   if (anExt == "sx")
99   {
100     QFile aFile (theFilePath);
101     
102     aFile.open(QIODevice::ReadOnly);
103
104     Parse(aFile);
105     aFile.close();
106     
107     return true;
108   }
109   else
110     return false;
111
112 }
113
114 void HYDROData_SinusX::Import(Handle(HYDROData_Document) theDocument,
115   NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities, std::vector<ImportOptions>* importOptions)
116 {
117   CollectExistingNames(theDocument);
118   SXToHydro(theDocument, theEntities, importOptions);
119 }
120
121
122 void HYDROData_SinusX::SXToHydro(Handle(HYDROData_Document) theDocument, NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities,
123     std::vector<ImportOptions>* importOptions )
124
125   if (importOptions && (myCurveBlocks.size() != importOptions->size()))
126     importOptions = NULL; //incorrect input
127
128   for ( size_t i = 0; i < myCurveBlocks.size(); i++ )
129   {
130     if (myCurveBlocks[i].myType == 4) ///  scatter plot -> to bathy
131     {
132       if (!importOptions || (importOptions && (*importOptions)[i].ImportAsBathy == true))
133       {
134         Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( theDocument->CreateObject( KIND_BATHYMETRY ) );
135         HYDROData_Bathymetry::AltitudePoints aAPoints;
136         size_t n = myCurveBlocks[i].myXYZPoints.size();
137         aAPoints.reserve( n );
138         for (size_t j = 0; j < n; j++)
139         {
140           gp_XYZ aLocalPoint = gp_XYZ (myCurveBlocks[i].myXYZPoints[j]);
141           theDocument->Transform(aLocalPoint, true);
142           HYDROData_Bathymetry::AltitudePoint p;
143           p.X = aLocalPoint.X();
144           p.Y = aLocalPoint.Y();
145           p.Z = aLocalPoint.Z();
146           aAPoints.push_back(p);
147         }
148
149         aBath->SetAltitudePoints(aAPoints);
150         aBath->SetName(GetName(myCurveBlocks[i].myName));
151         theEntities.Append(aBath);
152       }
153     }
154     if (myCurveBlocks[i].myType == 1 || myCurveBlocks[i].myType == 3) // XYZ curve or isocontour
155     {
156       if (!importOptions || (importOptions && (*importOptions)[i].ImportAsPolyXY == true))
157       {
158         NCollection_Sequence<gp_XYZ> aPoints;
159         for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
160         {
161           gp_XYZ aLocalPoint = gp_XYZ (myCurveBlocks[i].myXYZPoints[j]);
162           theDocument->Transform(aLocalPoint, true);
163           aPoints.Append(aLocalPoint);
164         }
165
166         Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( theDocument->CreateObject( KIND_POLYLINEXY ) );
167         aPolyXY->AddSection( "",  
168           myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE, 
169           myCurveBlocks[i].myIsClosed ? true : false); 
170         aPolyXY->SetName(GetName(myCurveBlocks[i].myName));
171         aPolyXY->SetWireColor(HYDROData_PolylineXY::DefaultWireColor());
172
173         for ( int k = 1; k <= aPoints.Size(); k++ ) {
174           const HYDROData_Profile::ProfilePoint& aBottomPoint = aPoints.Value( k );
175           aPolyXY->AddPoint( 0, HYDROData_PolylineXY::Point( aBottomPoint.X(), aBottomPoint.Y() ) );
176         }
177
178         theEntities.Append(aPolyXY);
179         if (!importOptions || (importOptions && (*importOptions)[i].ImportAsProfile == true))
180         {
181           Handle(HYDROData_ProfileUZ) aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast( theDocument->CreateObject( KIND_PROFILEUZ ) );
182           aProfileUZ->CalculateAndAddPoints(aPoints, aPolyXY, false);
183           Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
184           aProfile->SetParametricPoints(aProfileUZ->GetPoints());
185
186           aProfileUZ->SetName(GetName(myCurveBlocks[i].myName));
187           aProfile->SetName(GetName(myCurveBlocks[i].myName));
188
189           theEntities.Append(aProfileUZ);
190           theEntities.Append(aProfile);
191         }
192       }      
193
194     }
195     if (myCurveBlocks[i].myType == 2) // XYZ profile
196     {
197       if (!importOptions || (importOptions && (*importOptions)[i].ImportAsProfile == true))
198       {
199         if (myCurveBlocks[i].myCurvePlane == 2) // plane XoZ
200         {
201           if (myCurveBlocks[i].myAdditionalCurveInfo.size() == 4)
202           {
203             Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
204             HYDROData_ProfileUZ::PointsList aPointList;
205             for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
206               aPointList.Append(gp_XY (myCurveBlocks[i].myXYZPoints[j].X(), myCurveBlocks[i].myXYZPoints[j].Z()));
207             aProfile->GetProfileUZ()->SetSectionType(0,  myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
208             aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
209             aProfile->SetParametricPoints(aPointList);
210             if ( ! (myCurveBlocks[i].myAdditionalCurveInfo[0] == 0 &&  myCurveBlocks[i].myAdditionalCurveInfo[1] == 0 && 
211               myCurveBlocks[i].myAdditionalCurveInfo[2] == 0 && myCurveBlocks[i].myAdditionalCurveInfo[3] == 0) )
212             { // georeferenced profile
213               double xl = myCurveBlocks[i].myAdditionalCurveInfo[0];
214               double yl = myCurveBlocks[i].myAdditionalCurveInfo[1];
215               double xr = myCurveBlocks[i].myAdditionalCurveInfo[2];
216               double yr = myCurveBlocks[i].myAdditionalCurveInfo[3];
217               theDocument->Transform(xl, yl , true);
218               theDocument->Transform(xr, yr , true);
219               aProfile->SetLeftPoint(gp_XY(xl, yl));
220               aProfile->SetRightPoint(gp_XY(xr, yr));
221               aProfile->Update();
222             }
223             aProfile->SetName(GetName(myCurveBlocks[i].myName));
224             theEntities.Append(aProfile);
225           }
226         }
227         if (myCurveBlocks[i].myCurvePlane == 0) // plane XoY
228         {
229           Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
230           HYDROData_Profile::ProfilePoints aPointList;
231           for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
232           {
233             gp_XYZ aLocalPoint = gp_XYZ (myCurveBlocks[i].myXYZPoints[j]);
234             theDocument->Transform(aLocalPoint, true);
235             aPointList.Append(aLocalPoint);
236           }
237           aProfile->GetProfileUZ()->SetSectionType(0,  myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
238           aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
239           aProfile->SetProfilePoints(aPointList);
240           aProfile->SetName(GetName(myCurveBlocks[i].myName));
241           theEntities.Append(aProfile);
242         }
243       }
244     }
245   }
246
247 }
248  
249
250 bool HYDROData_SinusX::Parse(QFile& theFile)
251 {
252   if ( !theFile.isOpen() )
253     return false;
254
255   QString aLine;
256   QString aBLine;
257   QStringList aList;
258   QStringList aBList;
259   myCurveBlocks.clear();
260   bool aTotStat = true;
261
262   aLine = theFile.readLine().simplified();
263   aList = aLine.split( ' ', QString::SkipEmptyParts );
264
265   for (;!theFile.atEnd();) 
266   {
267     if (aList[0] == "B" && (aList[1] == "C" || aList[1] == "P" || aList[1] == "N" || aList[1] == "S" ))
268     {  
269       HYDROGUI_CurveBlock aCurveBlockInfo;
270       if (aList[1] == "C")
271         aCurveBlockInfo.myType = 1; // XYZ curve
272       else if (aList[1] == "P")
273         aCurveBlockInfo.myType = 2; // XYZ profile
274       else if (aList[1] == "N")
275         aCurveBlockInfo.myType = 3; // isocontour
276       else if (aList[1] == "S")
277         aCurveBlockInfo.myType = 4; // Scatter plot
278
279       if (aList.size() == 9)
280       {
281         for (int j = 2; j < 8; j++)
282           aCurveBlockInfo.myRefCoords.push_back(aList[j].toDouble());
283         aCurveBlockInfo.myRefRatio = aList[8].toDouble();
284       }
285
286       QString Name;
287       do
288       {
289         aBLine = theFile.readLine().simplified();
290         aBList = aBLine.split( ' ', QString::SkipEmptyParts );
291          
292         if (aBList[0] == "CP")
293         {
294           if (aBList.size() == 2 && (aBList[1] == "0" || aBList[1] == "1" || aBList[1] == "2"))
295             aCurveBlockInfo.myCurvePlane = aBList[1].toInt();
296           else if (aBList.size() == 3 && (aBList[1] == "0" || aBList[1] == "1") && (aBList[2] == "0" || aBList[2] == "1"))
297           {
298             aCurveBlockInfo.myIsClosed = aBList[1].toInt();
299             aCurveBlockInfo.myIsSpline = aBList[2].toInt();
300           }
301           else
302           {
303             for (int j = 1; j < aBList.size(); j++)
304               aCurveBlockInfo.myAdditionalCurveInfo.push_back(aBList[j].toDouble());
305           }
306         }
307         if (aBList[0] == "CN")
308         {
309            for (int i = 1; i < aBList.size(); i++)
310              Name += aBList[i] + "_";
311            if (Name.size() <= 1)
312              Name = "noname_";
313            Name.remove(Name.size() - 1, 1);
314            aCurveBlockInfo.myName = Name;
315         }
316       } while (!theFile.atEnd() && aBLine[0] == 'C' );
317
318       bool aStat;
319       aTotStat = true;
320       do
321       {
322         if (aBList.size() >= 3 && aBLine[0] != 'B' && aBLine[0] != 'C') {
323           gp_XYZ anXYZ;
324           anXYZ.SetX (aBList[0].toDouble(&aStat));  
325           aTotStat = aTotStat && aStat;
326           anXYZ.SetY (aBList[1].toDouble(&aStat));
327           aTotStat = aTotStat && aStat;
328           anXYZ.SetZ (aBList[2].toDouble(&aStat));
329           aTotStat = aTotStat && aStat;
330
331           aCurveBlockInfo.myXYZPoints.push_back(anXYZ);
332           
333           aBLine = theFile.readLine().simplified();
334           aBList = aBLine.split( ' ', QString::SkipEmptyParts );
335         }
336         else 
337           break;
338     
339       } while (!theFile.atEnd() || !aBLine.isEmpty());
340       if (aTotStat)
341         myCurveBlocks.push_back(aCurveBlockInfo);
342
343       aLine = aBLine;
344       aList = aBList;
345
346     }
347     else
348     {
349       aLine = theFile.readLine().simplified();
350       aList = aLine.split( ' ', QString::SkipEmptyParts );
351     }
352
353   }
354
355   return true;
356
357 }
358
359 bool HYDROData_SinusX::Export(const QString& theFilePath, const NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities)
360 {
361   if ( theFilePath.isEmpty() )
362   { 
363     return false;
364   }
365
366   QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
367
368   if (anExt == "sx")
369   {
370     QFile aFile (theFilePath);
371     
372     aFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
373
374     HydroToSX(aFile, theEntities);
375     
376     aFile.close();
377     
378     return true;
379   }
380   else
381     return false;
382
383 }
384
385 void HYDROData_SinusX::HydroToSX(QFile& theFile, const NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities)
386 {
387   QTextStream aTextStream(&theFile);
388   aTextStream << "C  Generated by HYDRO Module\n";
389   aTextStream << "C\n";
390
391   for (int i = 1; i <= theEntities.Size(); i++)
392   {
393     Handle(HYDROData_Entity) anEnt = theEntities.Value(i);
394     if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Bathymetry) ))
395     {
396       Handle(HYDROData_Bathymetry) aBathy = Handle(HYDROData_Bathymetry)::DownCast( anEnt );
397       HYDROData_Bathymetry::AltitudePoints anXYZPoints = aBathy->GetAltitudePoints(true);
398       //Write to stream
399       aTextStream << "B S\n";
400       aTextStream << "CN " << aBathy->GetName() << "\n";
401       aTextStream << "CP 0 0\n";
402       aTextStream << "CP 0\n";
403       for (size_t j = 0, m = anXYZPoints.size(); j < m; j++)
404         aTextStream << " " << QString::number(anXYZPoints[j].X, 'f', 3)  
405                     << " " << QString::number(anXYZPoints[j].Y, 'f', 3)  
406                     << " " << QString::number(anXYZPoints[j].Z, 'f', 3) << "\n"; 
407     }
408     else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_PolylineXY) ))
409     {
410       Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( anEnt );
411       for (int j = 0; j < aPolyXY->NbSections(); j++)
412       { 
413         //Collect data
414         bool IsClosed = aPolyXY->IsClosedSection(j);
415         bool IsSpline = false;
416         if (aPolyXY->GetSectionType(j) == HYDROData_PolylineXY::SECTION_SPLINE)
417           IsSpline = true;
418         HYDROData_PolylineXY::PointsList anXYPoints = aPolyXY->GetPoints(j, true);
419         //Write to stream
420         aTextStream << "B N\n";
421         aTextStream << "CN " << aPolyXY->GetName() << "\n";
422         aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
423         aTextStream << "CP 0.0\n";
424         aTextStream << "CP 0\n";
425         if (aPolyXY->NbSections() > 1)
426           aTextStream << "C " << aPolyXY->GetName() << "_section_" << QString::number(j) << "\n";
427         for (int k = anXYPoints.Lower(); k <= anXYPoints.Upper(); k++)
428          aTextStream << " " << QString::number(anXYPoints(k).X(), 'f', 3)  
429                      << " " << QString::number(anXYPoints(k).Y(), 'f', 3)  
430                      << " 0.000\n"; 
431       }
432     }
433     else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Profile) ))
434     {
435       //Collect data
436       Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( anEnt );
437       HYDROData_ProfileUZ::PointsList aPointList = aProfile->GetParametricPoints();
438       bool IsClosed = aProfile->GetProfileUZ(false)->IsClosedSection(0);;
439       bool IsSpline = false;
440       if (aProfile->GetProfileUZ(false)->GetSectionType(0) == HYDROData_PolylineXY::SECTION_SPLINE)
441         IsSpline = true;
442       //Write to stream
443       aTextStream << "B P\n";
444       aTextStream << "CN " << aProfile->GetName() << "\n";
445       aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
446       gp_XY aLeftPoint(0.0, 0.0);
447       gp_XY aRightPoint(0.0, 0.0);
448       if (aProfile->GetLeftPoint(aLeftPoint, true) && aProfile->GetRightPoint(aRightPoint, true))
449         aTextStream << "CP " << QString::number(aLeftPoint.X(), 'f', 3) << " " <<
450                                 QString::number(aLeftPoint.Y(), 'f', 3) << " " <<
451                                 QString::number(aRightPoint.X(), 'f', 3) << " " <<
452                                 QString::number(aRightPoint.Y(), 'f', 3) << "\n";
453       else
454         aTextStream << "CP 0.0 0.0 0.0 0.0\n";
455       aTextStream << "CP 2\n";
456       for (int k = aPointList.Lower(); k <= aPointList.Upper(); k++)
457          aTextStream << " " << QString::number(aPointList(k).X(), 'f', 3)  
458                      << " 0.000 "
459                      << QString::number(aPointList(k).Y(), 'f', 3) << "\n";  
460     }
461   }
462 }
463
464 std::vector<HYDROGUI_CurveBlock> HYDROData_SinusX::GetCurveBlocks() const
465 {
466   return myCurveBlocks;
467 }
468
469