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>
40 #include "HYDRO_trace.hxx"
42 HYDROData_SinusX::HYDROData_SinusX( )
46 HYDROData_SinusX::~HYDROData_SinusX()
50 void HYDROData_SinusX::CollectExistingNames(Handle(HYDROData_Document) theDocument)
52 HYDROData_Iterator anIter( theDocument );
54 myExistingNames.clear();
55 std::vector<int> anAllowedIndexes;
56 for( ; anIter.More(); anIter.Next() )
57 myExistingNames.push_back(anIter.Current()->GetName());
60 QString HYDROData_SinusX::GetName(const QString& theName)
62 if (myExistingNames.contains(theName))
64 QString aName = theName;
65 while (myExistingNames.contains(aName))
67 QStringList aList = aName.split("_");
68 int aLastInd = aName.lastIndexOf("_");
71 anInd = aList.last().toInt(&IsNum);
74 aName = aName.left(aLastInd) + "_";
75 aName+= QString::number(++anInd);
78 aName = theName + "_0";
81 myExistingNames.push_back(aName);
86 myExistingNames.push_back(theName);
93 bool HYDROData_SinusX::OpenAndParse(const QString& theFilePath)
95 if ( theFilePath.isEmpty() )
100 QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
104 QFile aFile (theFilePath);
106 aFile.open(QIODevice::ReadOnly);
118 void HYDROData_SinusX::Import(Handle(HYDROData_Document) theDocument,
119 NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities, std::vector<ImportOptions>* importOptions)
121 CollectExistingNames(theDocument);
122 SXToHydro(theDocument, theEntities, importOptions);
126 void HYDROData_SinusX::SXToHydro(Handle(HYDROData_Document) theDocument, NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities,
127 std::vector<ImportOptions>* importOptions )
129 if (importOptions && (myCurveBlocks.size() != importOptions->size()))
130 importOptions = NULL; //incorrect input
132 QMap<QString,Handle(HYDROData_PolylineXY) > polyMap;
134 for ( size_t i = 0; i < myCurveBlocks.size(); i++ )
136 if (myCurveBlocks[i].myType == 4) /// scatter plot -> to bathy
138 if (!importOptions || (importOptions && (*importOptions)[i].ImportAsBathy == true))
140 Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( theDocument->CreateObject( KIND_BATHYMETRY ) );
141 HYDROData_Bathymetry::AltitudePoints aAPoints;
142 size_t n = myCurveBlocks[i].myXYZPoints.size();
143 aAPoints.reserve( n );
144 for (size_t j = 0; j < n; j++)
146 gp_XYZ aLocalPoint = gp_XYZ (myCurveBlocks[i].myXYZPoints[j]);
147 theDocument->Transform(aLocalPoint, true);
148 HYDROData_Bathymetry::AltitudePoint p;
149 p.X = aLocalPoint.X();
150 p.Y = aLocalPoint.Y();
151 p.Z = aLocalPoint.Z();
152 aAPoints.push_back(p);
155 aBath->SetAltitudePoints(aAPoints);
156 aBath->SetName(GetName(myCurveBlocks[i].myName));
157 theEntities.Append(aBath);
160 if (myCurveBlocks[i].myType == 1 || myCurveBlocks[i].myType == 3) // XYZ curve or isocontour
162 if (!importOptions || (importOptions && (*importOptions)[i].ImportAsPolyXY == true))
164 NCollection_Sequence<gp_XYZ> aPoints;
165 for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
167 gp_XYZ aLocalPoint = gp_XYZ (myCurveBlocks[i].myXYZPoints[j]);
168 theDocument->Transform(aLocalPoint, true);
169 aPoints.Append(aLocalPoint);
172 QString polyName = myCurveBlocks[i].myName;
173 Handle(HYDROData_PolylineXY) aPolyXY;
174 if (polyMap.contains(polyName))
175 aPolyXY = polyMap[polyName];
178 aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( theDocument->CreateObject( KIND_POLYLINEXY ) );
179 polyMap[polyName] = aPolyXY;
180 aPolyXY->SetName(GetName(myCurveBlocks[i].myName));
181 aPolyXY->SetWireColor(HYDROData_PolylineXY::DefaultWireColor());
182 theEntities.Append(aPolyXY);
184 aPolyXY->AddSection( "",
185 myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE,
186 myCurveBlocks[i].myIsClosed ? true : false);
187 int numSec = aPolyXY->NbSections() -1;
189 for ( int k = 1; k <= aPoints.Size(); k++ ) {
190 const HYDROData_Profile::ProfilePoint& aBottomPoint = aPoints.Value( k );
191 aPolyXY->AddPoint( numSec, HYDROData_PolylineXY::Point( aBottomPoint.X(), aBottomPoint.Y() ) );
194 if (!importOptions || (importOptions && (*importOptions)[i].ImportAsProfile == true))
196 Handle(HYDROData_ProfileUZ) aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast( theDocument->CreateObject( KIND_PROFILEUZ ) );
197 aProfileUZ->CalculateAndAddPoints(aPoints, aPolyXY, false);
198 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
199 aProfile->SetParametricPoints(aProfileUZ->GetPoints());
201 aProfileUZ->SetName(GetName(myCurveBlocks[i].myName));
202 aProfile->SetName(GetName(myCurveBlocks[i].myName));
204 theEntities.Append(aProfileUZ);
205 theEntities.Append(aProfile);
210 if (myCurveBlocks[i].myType == 2) // XYZ profile
212 if (!importOptions || (importOptions && (*importOptions)[i].ImportAsProfile == true))
214 if (myCurveBlocks[i].myCurvePlane == 2) // plane XoZ
216 if (myCurveBlocks[i].myAdditionalCurveInfo.size() == 4)
218 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
219 HYDROData_ProfileUZ::PointsList aPointList;
220 for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
221 aPointList.Append(gp_XY (myCurveBlocks[i].myXYZPoints[j].X(), myCurveBlocks[i].myXYZPoints[j].Z()));
222 aProfile->GetProfileUZ()->SetSectionType(0, myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
223 aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
224 aProfile->SetParametricPoints(aPointList);
225 if ( ! (myCurveBlocks[i].myAdditionalCurveInfo[0] == 0 && myCurveBlocks[i].myAdditionalCurveInfo[1] == 0 &&
226 myCurveBlocks[i].myAdditionalCurveInfo[2] == 0 && myCurveBlocks[i].myAdditionalCurveInfo[3] == 0) )
227 { // georeferenced profile
228 double xl = myCurveBlocks[i].myAdditionalCurveInfo[0];
229 double yl = myCurveBlocks[i].myAdditionalCurveInfo[1];
230 double xr = myCurveBlocks[i].myAdditionalCurveInfo[2];
231 double yr = myCurveBlocks[i].myAdditionalCurveInfo[3];
232 theDocument->Transform(xl, yl , true);
233 theDocument->Transform(xr, yr , true);
234 aProfile->SetLeftPoint(gp_XY(xl, yl));
235 aProfile->SetRightPoint(gp_XY(xr, yr));
238 aProfile->SetName(GetName(myCurveBlocks[i].myName));
239 theEntities.Append(aProfile);
242 if (myCurveBlocks[i].myCurvePlane == 0) // plane XoY
244 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
245 HYDROData_Profile::ProfilePoints aPointList;
246 for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
248 gp_XYZ aLocalPoint = gp_XYZ (myCurveBlocks[i].myXYZPoints[j]);
249 theDocument->Transform(aLocalPoint, true);
250 aPointList.Append(aLocalPoint);
252 aProfile->GetProfileUZ()->SetSectionType(0, myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
253 aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
254 aProfile->SetProfilePoints(aPointList, false);
255 aProfile->SetName(GetName(myCurveBlocks[i].myName));
256 theEntities.Append(aProfile);
265 bool HYDROData_SinusX::Parse(QFile& theFile)
267 if ( !theFile.isOpen() )
274 myCurveBlocks.clear();
275 bool aTotStat = true;
277 aLine = theFile.readLine().simplified();
278 aList = aLine.split( ' ', QString::SkipEmptyParts );
280 for (;!theFile.atEnd();)
282 if (aList[0] == "B" && (aList[1] == "C" || aList[1] == "P" || aList[1] == "N" || aList[1] == "S" ))
284 HYDROGUI_CurveBlock aCurveBlockInfo;
286 aCurveBlockInfo.myType = 1; // XYZ curve
287 else if (aList[1] == "P")
288 aCurveBlockInfo.myType = 2; // XYZ profile
289 else if (aList[1] == "N")
290 aCurveBlockInfo.myType = 3; // isocontour
291 else if (aList[1] == "S")
292 aCurveBlockInfo.myType = 4; // Scatter plot
294 if (aList.size() == 9)
296 for (int j = 2; j < 8; j++)
297 aCurveBlockInfo.myRefCoords.push_back(aList[j].toDouble());
298 aCurveBlockInfo.myRefRatio = aList[8].toDouble();
304 aBLine = theFile.readLine().simplified();
305 aBList = aBLine.split( ' ', QString::SkipEmptyParts );
307 if (aBList[0] == "CP")
309 if (aBList.size() == 2 && (aBList[1] == "0" || aBList[1] == "1" || aBList[1] == "2"))
310 aCurveBlockInfo.myCurvePlane = aBList[1].toInt();
311 else if (aBList.size() == 3 && (aBList[1] == "0" || aBList[1] == "1") && (aBList[2] == "0" || aBList[2] == "1"))
313 aCurveBlockInfo.myIsClosed = aBList[1].toInt();
314 aCurveBlockInfo.myIsSpline = aBList[2].toInt();
318 for (int j = 1; j < aBList.size(); j++)
319 aCurveBlockInfo.myAdditionalCurveInfo.push_back(aBList[j].toDouble());
322 if (aBList[0] == "CN")
324 for (int i = 1; i < aBList.size(); i++)
325 Name += aBList[i] + "_";
326 if (Name.size() <= 1)
328 Name.remove(Name.size() - 1, 1);
329 aCurveBlockInfo.myName = Name;
331 } while (!theFile.atEnd() && aBLine[0] == 'C' );
337 if (aBList.size() >= 3 && aBLine[0] != 'B' && aBLine[0] != 'C') {
339 anXYZ.SetX (aBList[0].toDouble(&aStat));
340 aTotStat = aTotStat && aStat;
341 anXYZ.SetY (aBList[1].toDouble(&aStat));
342 aTotStat = aTotStat && aStat;
343 anXYZ.SetZ (aBList[2].toDouble(&aStat));
344 aTotStat = aTotStat && aStat;
346 aCurveBlockInfo.myXYZPoints.push_back(anXYZ);
348 aBLine = theFile.readLine().simplified();
349 aBList = aBLine.split( ' ', QString::SkipEmptyParts );
354 } while (!theFile.atEnd() || !aBLine.isEmpty());
356 myCurveBlocks.push_back(aCurveBlockInfo);
364 aLine = theFile.readLine().simplified();
365 aList = aLine.split( ' ', QString::SkipEmptyParts );
374 bool HYDROData_SinusX::Export(const QString& theFilePath, const NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities)
376 if ( theFilePath.isEmpty() )
381 QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
385 QFile aFile (theFilePath);
387 aFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
389 HydroToSX(aFile, theEntities);
400 void HYDROData_SinusX::HydroToSX(QFile& theFile, const NCollection_Sequence<Handle(HYDROData_Entity)>& theEntities)
402 QTextStream aTextStream(&theFile);
403 aTextStream << "C Generated by HYDRO Module\n";
404 aTextStream << "C\n";
406 for (int i = 1; i <= theEntities.Size(); i++)
408 Handle(HYDROData_Entity) anEnt = theEntities.Value(i);
409 if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Bathymetry) ))
411 Handle(HYDROData_Bathymetry) aBathy = Handle(HYDROData_Bathymetry)::DownCast( anEnt );
412 HYDROData_Bathymetry::AltitudePoints anXYZPoints = aBathy->GetAltitudePoints(true);
414 aTextStream << "B S\n";
415 aTextStream << "CN " << aBathy->GetName() << "\n";
416 aTextStream << "CP 0 0\n";
417 aTextStream << "CP 0\n";
418 for (size_t j = 0, m = anXYZPoints.size(); j < m; j++)
419 aTextStream << " " << QString::number(anXYZPoints[j].X, 'f', 3)
420 << " " << QString::number(anXYZPoints[j].Y, 'f', 3)
421 << " " << QString::number(anXYZPoints[j].Z, 'f', 3) << "\n";
423 else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_PolylineXY) ))
425 Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( anEnt );
426 for (int j = 0; j < aPolyXY->NbSections(); j++)
429 bool IsClosed = aPolyXY->IsClosedSection(j);
430 bool IsSpline = false;
431 if (aPolyXY->GetSectionType(j) == HYDROData_PolylineXY::SECTION_SPLINE)
433 HYDROData_PolylineXY::PointsList anXYPoints = aPolyXY->GetPoints(j, true);
435 aTextStream << "B N\n";
436 aTextStream << "CN " << aPolyXY->GetName() << "\n";
437 aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
438 aTextStream << "CP 0.0\n";
439 aTextStream << "CP 0\n";
440 if (aPolyXY->NbSections() > 1)
441 aTextStream << "C " << aPolyXY->GetName() << "_section_" << QString::number(j) << "\n";
442 for (int k = anXYPoints.Lower(); k <= anXYPoints.Upper(); k++)
443 aTextStream << " " << QString::number(anXYPoints(k).X(), 'f', 3)
444 << " " << QString::number(anXYPoints(k).Y(), 'f', 3)
448 else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Profile) ))
451 Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( anEnt );
452 HYDROData_ProfileUZ::PointsList aPointList = aProfile->GetParametricPoints();
453 bool IsClosed = aProfile->GetProfileUZ(false)->IsClosedSection(0);;
454 bool IsSpline = false;
455 if (aProfile->GetProfileUZ(false)->GetSectionType(0) == HYDROData_PolylineXY::SECTION_SPLINE)
458 aTextStream << "B P\n";
459 aTextStream << "CN " << aProfile->GetName() << "\n";
460 aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
461 gp_XY aLeftPoint(0.0, 0.0);
462 gp_XY aRightPoint(0.0, 0.0);
463 if (aProfile->GetLeftPoint(aLeftPoint, true) && aProfile->GetRightPoint(aRightPoint, true))
464 aTextStream << "CP " << QString::number(aLeftPoint.X(), 'f', 3) << " " <<
465 QString::number(aLeftPoint.Y(), 'f', 3) << " " <<
466 QString::number(aRightPoint.X(), 'f', 3) << " " <<
467 QString::number(aRightPoint.Y(), 'f', 3) << "\n";
469 aTextStream << "CP 0.0 0.0 0.0 0.0\n";
470 aTextStream << "CP 2\n";
471 for (int k = aPointList.Lower(); k <= aPointList.Upper(); k++)
472 aTextStream << " " << QString::number(aPointList(k).X(), 'f', 3)
474 << QString::number(aPointList(k).Y(), 'f', 3) << "\n";
479 std::vector<HYDROGUI_CurveBlock> HYDROData_SinusX::GetCurveBlocks() const
481 return myCurveBlocks;