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.
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.
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
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROData_SinusX.h"
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>
34 #include <QStringList>
35 #include <QTextStream>
38 HYDROData_SinusX::HYDROData_SinusX( )
42 HYDROData_SinusX::~HYDROData_SinusX()
46 void HYDROData_SinusX::CollectExistingNames(Handle_HYDROData_Document theDocument)
48 HYDROData_Iterator anIter( theDocument );
50 myExistingNames.clear();
51 std::vector<int> anAllowedIndexes;
52 for( ; anIter.More(); anIter.Next() )
53 myExistingNames.push_back(anIter.Current()->GetName());
56 QString HYDROData_SinusX::GetName(const QString& theName)
58 if (myExistingNames.contains(theName))
60 QString aName = theName;
61 while (myExistingNames.contains(aName))
63 QStringList aList = aName.split("_");
64 int aLastInd = aName.lastIndexOf("_");
67 anInd = aList.last().toInt(&IsNum);
70 aName = aName.left(aLastInd) + "_";
71 aName+= QString::number(++anInd);
74 aName = theName + "_0";
77 myExistingNames.push_back(aName);
82 myExistingNames.push_back(theName);
89 bool HYDROData_SinusX::Import(const QString& theFilePath, Handle(HYDROData_Document) theDocument, NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
91 if ( theFilePath.isEmpty() )
96 QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
100 QFile aFile (theFilePath);
102 aFile.open(QIODevice::ReadOnly);
106 CollectExistingNames(theDocument);
107 SXToHydro(theDocument, theEntities);
118 void HYDROData_SinusX::SXToHydro(Handle(HYDROData_Document) theDocument, NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
120 for ( size_t i = 0; i < myCurveBlocks.size(); i++ )
122 if (myCurveBlocks[i].myType == 4) /// scatter plot -> to bathy
124 Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( theDocument->CreateObject( KIND_BATHYMETRY ) );
125 HYDROData_Bathymetry::AltitudePoints aAPoints;
126 for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
127 aAPoints.Append(gp_XYZ (myCurveBlocks[i].myXYZPoints[j]));
129 aBath->SetAltitudePoints(aAPoints);
130 aBath->SetName(GetName(myCurveBlocks[i].myName + "_bath"));
131 theEntities.Append(aBath);
133 if (myCurveBlocks[i].myType == 1 || myCurveBlocks[i].myType == 3)
135 NCollection_Sequence<gp_XYZ> aPoints;
136 for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
137 aPoints.Append(gp_XYZ (myCurveBlocks[i].myXYZPoints[j]));
138 /*if (myCurveBlocks[i].myIsClosed)
139 aPoints.Append(gp_XYZ (myCurveBlocks[i].myXYZPoints[0]));*/
140 Handle(HYDROData_ProfileUZ) aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast( theDocument->CreateObject( KIND_PROFILEUZ ) );
141 Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( theDocument->CreateObject( KIND_POLYLINEXY ) );
142 aPolyXY->AddSection( "",
143 myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE,
144 myCurveBlocks[i].myIsClosed ? true : false);
145 aProfileUZ->CalculateAndAddPoints(aPoints, aPolyXY);
146 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
147 aProfile->SetParametricPoints(aProfileUZ->GetPoints());
148 aPolyXY->SetName(GetName(myCurveBlocks[i].myName + "_polyXY"));
149 aProfileUZ->SetName(GetName(myCurveBlocks[i].myName + "_profileUZ"));
150 aProfile->SetName(GetName(myCurveBlocks[i].myName + "_profile"));
151 aPolyXY->SetWireColor(HYDROData_PolylineXY::DefaultWireColor());
152 theEntities.Append(aPolyXY);
153 theEntities.Append(aProfileUZ);
154 theEntities.Append(aProfile);
156 if (myCurveBlocks[i].myType == 2)
158 if (myCurveBlocks[i].myCurvePlane == 2)
160 if (myCurveBlocks[i].myAdditionalCurveInfo.size() == 4)
162 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
163 HYDROData_ProfileUZ::PointsList aPointList;
164 for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
165 aPointList.Append(gp_XY (myCurveBlocks[i].myXYZPoints[j].X(), myCurveBlocks[i].myXYZPoints[j].Z()));
166 aProfile->GetProfileUZ()->SetSectionType(0, myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
167 aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
168 aProfile->SetParametricPoints(aPointList);
169 if ( ! (myCurveBlocks[i].myAdditionalCurveInfo[0] == 0 && myCurveBlocks[i].myAdditionalCurveInfo[1] == 0 &&
170 myCurveBlocks[i].myAdditionalCurveInfo[2] == 0 && myCurveBlocks[i].myAdditionalCurveInfo[3] == 0) )
172 aProfile->SetLeftPoint(gp_XY(myCurveBlocks[i].myAdditionalCurveInfo[0], myCurveBlocks[i].myAdditionalCurveInfo[1]));
173 aProfile->SetRightPoint(gp_XY(myCurveBlocks[i].myAdditionalCurveInfo[2], myCurveBlocks[i].myAdditionalCurveInfo[3]));
176 aProfile->SetName(GetName(myCurveBlocks[i].myName + "_profile"));
177 theEntities.Append(aProfile);
180 if (myCurveBlocks[i].myCurvePlane == 0)
182 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
183 HYDROData_Profile::ProfilePoints aPointList;
184 for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
185 aPointList.Append(myCurveBlocks[i].myXYZPoints[j]);
186 aProfile->GetProfileUZ()->SetSectionType(0, myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
187 aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
188 aProfile->SetProfilePoints(aPointList);
189 aProfile->SetName(GetName(myCurveBlocks[i].myName + "_profile"));
190 theEntities.Append(aProfile);
198 bool HYDROData_SinusX::Parse(QFile& theFile)
200 if ( !theFile.isOpen() )
207 myCurveBlocks.clear();
208 bool aTotStat = true;
210 aLine = theFile.readLine().simplified();
211 aList = aLine.split( ' ', QString::SkipEmptyParts );
213 for (;!theFile.atEnd();)
215 if (aList[0] == "B" && (aList[1] == "C" || aList[1] == "P" || aList[1] == "N" || aList[1] == "S" ))
217 HYDROGUI_CurveBlock aCurveBlockInfo;
219 aCurveBlockInfo.myType = 1;
220 else if (aList[1] == "P")
221 aCurveBlockInfo.myType = 2;
222 else if (aList[1] == "N")
223 aCurveBlockInfo.myType = 3;
224 else if (aList[1] == "S")
225 aCurveBlockInfo.myType = 4;
227 if (aList.size() == 9)
229 for (int j = 2; j < 8; j++)
230 aCurveBlockInfo.myRefCoords.push_back(aList[j].toDouble());
231 aCurveBlockInfo.myRefRatio = aList[8].toDouble();
237 aBLine = theFile.readLine().simplified();
238 aBList = aBLine.split( ' ', QString::SkipEmptyParts );
240 if (aBList[0] == "CP")
242 if (aBList.size() == 2 && (aBList[1] == "0" || aBList[1] == "1" || aBList[1] == "2"))
243 aCurveBlockInfo.myCurvePlane = aBList[1].toInt();
244 else if (aBList.size() == 3 && (aBList[1] == "0" || aBList[1] == "1") && (aBList[2] == "0" || aBList[2] == "1"))
246 aCurveBlockInfo.myIsClosed = aBList[1].toInt();
247 aCurveBlockInfo.myIsSpline = aBList[2].toInt();
251 for (int j = 1; j < aBList.size(); j++)
252 aCurveBlockInfo.myAdditionalCurveInfo.push_back(aBList[j].toDouble());
255 if (aBList[0] == "CN")
257 for (int i = 1; i < aBList.size(); i++)
258 Name += aBList[i] + "_";
259 Name.remove(Name.size() - 1, 1);
260 aCurveBlockInfo.myName = Name;
262 } while (!theFile.atEnd() && aBLine[0] == 'C' );
268 if (aBList.size() >= 3 && aBLine[0] != 'B' && aBLine[0] != 'C') {
270 anXYZ.SetX (aBList[0].toDouble(&aStat));
271 aTotStat = aTotStat && aStat;
272 anXYZ.SetY (aBList[1].toDouble(&aStat));
273 aTotStat = aTotStat && aStat;
274 anXYZ.SetZ (aBList[2].toDouble(&aStat));
275 aTotStat = aTotStat && aStat;
277 aCurveBlockInfo.myXYZPoints.push_back(anXYZ);
279 aBLine = theFile.readLine().simplified();
280 aBList = aBLine.split( ' ', QString::SkipEmptyParts );
285 } while (!theFile.atEnd() || !aBLine.isEmpty());
287 myCurveBlocks.push_back(aCurveBlockInfo);
295 aLine = theFile.readLine().simplified();
296 aList = aLine.split( ' ', QString::SkipEmptyParts );
305 bool HYDROData_SinusX::Export(const QString& theFilePath, const NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
307 if ( theFilePath.isEmpty() )
312 QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
316 QFile aFile (theFilePath);
318 aFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
320 HydroToSX(aFile, theEntities);
331 void HYDROData_SinusX::HydroToSX(QFile& theFile, const NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
333 QTextStream aTextStream(&theFile);
334 aTextStream << "C Generated by HYDRO Module\n";
335 aTextStream << "C\n";
337 for (int i = 1; i <= theEntities.Size(); i++)
339 Handle_HYDROData_Entity anEnt = theEntities.Value(i);
340 if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Bathymetry) ))
342 Handle(HYDROData_Bathymetry) aBathy = Handle(HYDROData_Bathymetry)::DownCast( anEnt );
343 HYDROData_Bathymetry::AltitudePoints anXYZPoints = aBathy->GetAltitudePoints(true);
345 aTextStream << "B S\n";
346 aTextStream << "CN " << aBathy->GetName() << "\n";
347 aTextStream << "CP 0 0\n";
348 aTextStream << "CP 0\n";
349 for (int j = anXYZPoints.Lower(); j <= anXYZPoints.Upper(); j++)
350 aTextStream << " " << QString::number(anXYZPoints(j).X(), 'f', 3)
351 << " " << QString::number(anXYZPoints(j).Y(), 'f', 3)
352 << " " << QString::number(anXYZPoints(j).Z(), 'f', 3) << "\n";
354 else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_PolylineXY) ))
356 Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( anEnt );
357 for (int j = 0; j < aPolyXY->NbSections(); j++)
360 bool IsClosed = aPolyXY->IsClosedSection(j);
361 bool IsSpline = false;
362 if (aPolyXY->GetSectionType(j) == HYDROData_PolylineXY::SECTION_SPLINE)
364 HYDROData_PolylineXY::PointsList anXYPoints = aPolyXY->GetPoints(j, true);
366 aTextStream << "B N\n";
367 aTextStream << "CN " << aPolyXY->GetName() << "\n";
368 aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
369 aTextStream << "CP 0.0\n";
370 aTextStream << "CP 0\n";
371 if (aPolyXY->NbSections() > 1)
372 aTextStream << "C " << aPolyXY->GetName() << "_section_" << QString::number(j) << "\n";
373 for (int k = anXYPoints.Lower(); k <= anXYPoints.Upper(); k++)
374 aTextStream << " " << QString::number(anXYPoints(k).X(), 'f', 3)
375 << " " << QString::number(anXYPoints(k).Y(), 'f', 3)
379 else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Profile) ))
382 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( anEnt );
383 HYDROData_ProfileUZ::PointsList aPointList = aProfile->GetParametricPoints();
384 bool IsClosed = aProfile->GetProfileUZ(false)->IsClosedSection(0);;
385 bool IsSpline = false;
386 if (aProfile->GetProfileUZ(false)->GetSectionType(0) == HYDROData_PolylineXY::SECTION_SPLINE)
389 aTextStream << "B P\n";
390 aTextStream << "CN " << aProfile->GetName() << "\n";
391 aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
392 gp_XY aLeftPoint(0.0, 0.0);
393 gp_XY aRightPoint(0.0, 0.0);
394 if (aProfile->GetLeftPoint(aLeftPoint, true) && aProfile->GetRightPoint(aRightPoint, true))
395 aTextStream << "CP " << QString::number(aLeftPoint.X(), 'f', 3) << " " <<
396 QString::number(aLeftPoint.Y(), 'f', 3) << " " <<
397 QString::number(aRightPoint.X(), 'f', 3) << " " <<
398 QString::number(aRightPoint.Y(), 'f', 3) << "\n";
400 aTextStream << "CP 0.0 0.0 0.0 0.0\n";
401 aTextStream << "CP 2\n";
402 for (int k = aPointList.Lower(); k <= aPointList.Upper(); k++)
403 aTextStream << " " << QString::number(aPointList(k).X(), 'f', 3)
405 << QString::number(aPointList(k).Y(), 'f', 3) << "\n";