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