2 #include "HYDROData_Profile.h"
4 #include "HYDROData_Document.h"
5 #include "HYDROData_Iterator.h"
6 #include "HYDROData_Tool.h"
7 #include "HYDROData_PolylineXY.h"
9 #include <boost/math/special_functions/fpclassify.hpp>
11 #include <BRepBuilderAPI_MakeEdge.hxx>
12 #include <BRepBuilderAPI_MakeWire.hxx>
13 #include <BRepBuilderAPI_MakePolygon.hxx>
17 #include <gp_Pnt2d.hxx>
19 #include <TDataStd_AsciiString.hxx>
20 #include <TDataStd_RealArray.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Wire.hxx>
25 #include <OSD_File.hxx>
26 #include <OSD_Protection.hxx>
29 #include <QStringList>
31 IMPLEMENT_STANDARD_HANDLE(HYDROData_Profile, HYDROData_Object)
32 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Profile, HYDROData_Object)
34 HYDROData_Profile::HYDROData_Profile()
39 HYDROData_Profile::~HYDROData_Profile()
43 QStringList HYDROData_Profile::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
45 QStringList aResList = dumpObjectCreation( theTreatedObjects );
46 QString aName = GetName();
48 QColor aFillingColor = GetFillingColor();
49 aResList << QString( "filling_color = QColor( %1, %2, %3, %4 );" )
50 .arg( aFillingColor.red() ).arg( aFillingColor.green() )
51 .arg( aFillingColor.blue() ).arg( aFillingColor.alpha() );
52 aResList << QString( "%1.SetFillingColor( filling_color );" ).arg( aName );
53 aResList << QString( "" );
55 QColor aBorderColor = GetBorderColor();
56 aResList << QString( "border_color = QColor( %1, %2, %3, %4 );" )
57 .arg( aBorderColor.red() ).arg( aBorderColor.green() )
58 .arg( aBorderColor.blue() ).arg( aBorderColor.alpha() );
59 aResList << QString( "%1.SetBorderColor( border_color );" ).arg( aName );
60 aResList << QString( "" );
62 //TCollection_AsciiString aFilePath = GetFilePath();
63 //if ( !aFilePath.IsEmpty() )
65 // aResList << QString( "%1.ImportFromFile( \"%2\" );" )
66 // .arg( aName ).arg( aFilePath.ToCString() );
69 bool isValid = IsValid();
70 QString aGap = QString().fill( ' ', 11 );
72 aResList << QString( "points = [" );
76 HYDROData_Profile::ProfilePoints aPointsList = GetProfilePoints();
77 for ( int k = 1, aNbPoints = aPointsList.Size(); k <= aNbPoints; ++k )
79 const ProfilePoint& aPoint = aPointsList.Value( k );
80 aResList << QString( aGap + "gp_XYZ( %1, %2, %3 )%4" ).arg( aPoint.X() ).arg( aPoint.Y() ).arg( aPoint.Z() )
81 .arg( ( k < aNbPoints ? "," : "" ) );
83 aResList << QString( "];" );
84 aResList << QString( "%1.SetProfilePoints( points );" ).arg( aName );
88 HYDROData_IPolyline::PointsList aPointsList = GetParametricPoints();
89 for ( int k = 1, aNbPoints = aPointsList.Size(); k <= aNbPoints; ++k )
91 const HYDROData_IPolyline::Point& aPoint = aPointsList.Value( k );
92 aResList << QString( aGap + "gp_XY( %1, %2 )%3" ).arg( aPoint.X() ).arg( aPoint.Y() )
93 .arg( ( k < aNbPoints ? "," : "" ) );
95 aResList << QString( "];" );
96 aResList << QString( "%1.SetParametricPoints( points )" ).arg( aName );
98 aResList << QString( "" );
99 aResList << QString( "%1.Update();" ).arg( aName );
100 aResList << QString( "" );
105 TopoDS_Shape HYDROData_Profile::GetTopShape() const
109 gp_XY aFirstPoint, aLastPoint;
110 if ( !GetLeftPoint( aFirstPoint ) || !GetRightPoint( aLastPoint ) )
113 gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
114 gp_Pnt aPnt2( aLastPoint.X(), aLastPoint.Y(), 0 );
116 BRepBuilderAPI_MakeEdge aMakeEdge( aPnt1, aPnt2 );
117 TopoDS_Edge anEdge = aMakeEdge;
119 BRepBuilderAPI_MakeWire aMakeWire( anEdge );
125 TopoDS_Shape HYDROData_Profile::GetShape3D() const
130 void HYDROData_Profile::Update()
132 HYDROData_Object::Update();
135 Handle(HYDROData_ProfileUZ) aProfile = GetProfileUZ( false );
136 if ( !aProfile.IsNull() )
138 ProfilePoints aProfilePoints = GetProfilePoints();
139 HYDROData_IPolyline::SectionType aSectionType = aProfile->GetSectionType( 0 );
141 aWire = HYDROData_PolylineXY::BuildWire( aSectionType, false, aProfilePoints );
146 QColor HYDROData_Profile::DefaultFillingColor()
148 return QColor( Qt::transparent );
151 QColor HYDROData_Profile::DefaultBorderColor()
153 return QColor( Qt::black );
156 QColor HYDROData_Profile::getDefaultFillingColor() const
158 return DefaultFillingColor();
161 QColor HYDROData_Profile::getDefaultBorderColor() const
163 return DefaultBorderColor();
166 bool HYDROData_Profile::IsValid() const
168 gp_XY aFirstPoint, aLastPoint;
169 if ( !GetLeftPoint( aFirstPoint ) || !GetRightPoint( aLastPoint ) )
172 int aNbPoints = NbPoints();
173 return aNbPoints > 1;
176 void HYDROData_Profile::SetLeftPoint( const gp_XY& thePoint )
178 TDF_Label aLabel = myLab.FindChild( DataTag_FirstPoint );
180 Handle(TDataStd_RealArray) anArray;
181 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
182 anArray = TDataStd_RealArray::Set( aLabel, 0, 1 );
184 anArray->SetValue( 0, thePoint.X() );
185 anArray->SetValue( 1, thePoint.Y() );
190 bool HYDROData_Profile::GetLeftPoint( gp_XY& thePoint ) const
192 TDF_Label aLabel = myLab.FindChild( DataTag_FirstPoint, false );
193 if ( aLabel.IsNull() )
196 Handle(TDataStd_RealArray) anArray;
197 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
200 thePoint.SetX( anArray->Value( 0 ) );
201 thePoint.SetY( anArray->Value( 1 ) );
206 void HYDROData_Profile::SetRightPoint( const gp_XY& thePoint )
208 TDF_Label aLabel = myLab.FindChild( DataTag_LastPoint );
210 Handle(TDataStd_RealArray) anArray;
211 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
212 anArray = TDataStd_RealArray::Set( aLabel, 0, 1 );
214 anArray->SetValue( 0, thePoint.X() );
215 anArray->SetValue( 1, thePoint.Y() );
220 bool HYDROData_Profile::GetRightPoint( gp_XY& thePoint ) const
222 TDF_Label aLabel = myLab.FindChild( DataTag_LastPoint, false );
223 if ( aLabel.IsNull() )
226 Handle(TDataStd_RealArray) anArray;
227 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
230 thePoint.SetX( anArray->Value( 0 ) );
231 thePoint.SetY( anArray->Value( 1 ) );
236 void HYDROData_Profile::Invalidate()
238 TDF_Label aFirstLabel = myLab.FindChild( DataTag_FirstPoint, false );
239 if ( !aFirstLabel.IsNull() )
240 aFirstLabel.ForgetAllAttributes();
242 TDF_Label aLastLabel = myLab.FindChild( DataTag_LastPoint, false );
243 if ( !aLastLabel.IsNull() )
244 aLastLabel.ForgetAllAttributes();
249 Handle(HYDROData_ProfileUZ) HYDROData_Profile::GetProfileUZ( const bool theIsCreate ) const
251 Handle(HYDROData_ProfileUZ) aProfileUZ;
253 TDF_Label aLabel = myLab.FindChild( DataTag_ChildProfileUZ, theIsCreate );
254 if ( aLabel.IsNull() )
257 aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast( HYDROData_Iterator::Object( aLabel ) );
258 if ( aProfileUZ.IsNull() && theIsCreate )
260 aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast(
261 HYDROData_Iterator::CreateObject( aLabel, KIND_PROFILEUZ ) );
267 int HYDROData_Profile::NbPoints() const
269 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
270 return aProfileUZ.IsNull() ? 0 : aProfileUZ->NbPoints();
273 void HYDROData_Profile::RemovePoints()
275 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
276 if ( !aProfileUZ.IsNull() )
278 aProfileUZ->RemoveSections();
283 void HYDROData_Profile::SetParametricPoints( const HYDROData_ProfileUZ::PointsList& thePoints )
287 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
288 for ( int i = 1, n = thePoints.Length(); i <= n ; ++i )
290 const HYDROData_ProfileUZ::Point& aPoint = thePoints.Value( i );
291 aProfileUZ->AddPoint( 0, aPoint );
297 HYDROData_ProfileUZ::PointsList HYDROData_Profile::GetParametricPoints() const
299 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
300 return aProfileUZ.IsNull() ? HYDROData_ProfileUZ::PointsList() : aProfileUZ->GetPoints();
303 void HYDROData_Profile::SetProfilePoints( const ProfilePoints& thePoints )
306 if ( thePoints.Length() < 2 )
309 gp_XY aFirstPoint, aLastPoint;
311 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
312 for ( int i = 1, n = thePoints.Length(); i <= n ; ++i )
314 const ProfilePoint& aPoint = thePoints.Value( i );
315 gp_XY aPointXY( aPoint.X(), aPoint.Y() );
318 aFirstPoint = aPointXY;
320 aLastPoint = aPointXY;
322 double aDistance = gp_Pnt2d( aFirstPoint ).Distance( aPointXY );
324 HYDROData_ProfileUZ::Point aParPoint( aDistance, aPoint.Z() );
325 aProfileUZ->AddPoint( 0, aParPoint );
328 SetLeftPoint( aFirstPoint );
329 SetRightPoint( aLastPoint );
332 HYDROData_Profile::ProfilePoints HYDROData_Profile::GetProfilePoints() const
334 ProfilePoints aResPoints;
336 gp_XY aFirstPoint, aLastPoint;
337 if ( !GetLeftPoint( aFirstPoint ) || !GetRightPoint( aLastPoint ) )
340 HYDROData_ProfileUZ::PointsList aParametricPoints = GetParametricPoints();
341 if ( aParametricPoints.Length() < 2 )
344 const HYDROData_ProfileUZ::Point& aFirstParPoint = aParametricPoints.First();
345 const HYDROData_ProfileUZ::Point& aLastParPoint = aParametricPoints.Last();
347 double aGeoDistance = gp_Pnt2d( aFirstPoint ).Distance( aLastPoint );
348 double aParCommonDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aLastParPoint.X(), 0 ) );
350 // Add first point as is
351 aResPoints.Append( ProfilePoint( aFirstPoint.X(), aFirstPoint.Y(), aFirstParPoint.Y() ) );
353 // Compute all other points
354 for ( int i = 2, n = aParametricPoints.Length(); i < n ; ++i )
356 const HYDROData_ProfileUZ::Point& aParPoint = aParametricPoints.Value( i );
358 double aParPointDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aParPoint.X(), 0 ) );
360 double aParLen = ( aParPointDist / aParCommonDist ) * aGeoDistance;
362 double aRatio = aParLen / ( aGeoDistance - aParLen );
364 double aParX = ( aFirstPoint.X() + aRatio * aLastPoint.X() ) / ( 1 + aRatio );
365 double aParY = ( aFirstPoint.Y() + aRatio * aLastPoint.Y() ) / ( 1 + aRatio );
367 ProfilePoint aCompPoint( aParX, aParY, aParPoint.Y() );
368 aResPoints.Append( aCompPoint );
371 // Add last point as is
372 aResPoints.Append( ProfilePoint( aLastPoint.X(), aLastPoint.Y(), aLastParPoint.Y() ) );
377 void HYDROData_Profile::SetFilePath( const TCollection_AsciiString& theFilePath )
379 TDataStd_AsciiString::Set( myLab.FindChild( DataTag_FilePath ), theFilePath );
382 TCollection_AsciiString HYDROData_Profile::GetFilePath() const
384 TCollection_AsciiString aRes;
386 Handle(TDataStd_AsciiString) anAsciiStr;
387 if ( myLab.FindChild( DataTag_FilePath ).FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) )
388 aRes = anAsciiStr->Get();
393 int HYDROData_Profile::ImportFromFile( const Handle(HYDROData_Document)& theDoc,
394 const TCollection_AsciiString& theFileName,
395 NCollection_Sequence<int>& theBadProfilesIds )
397 if ( theDoc.IsNull() || theFileName.IsEmpty() )
400 OSD_File aFile( theFileName );
401 if ( !aFile.IsReadable() )
404 aFile.Open( OSD_ReadOnly, OSD_Protection() );
405 if ( !aFile.IsOpen() )
408 NCollection_Sequence<Handle(HYDROData_Profile)> aCreatedProfiles;
411 Handle(HYDROData_Profile) aNewProfile;
412 for ( ; !aFile.IsAtEnd(); ++aProfileId )
414 if ( aNewProfile.IsNull() )
415 aNewProfile = Handle(HYDROData_Profile)::DownCast( theDoc->CreateObject( KIND_PROFILE ) );
417 bool anIsRead = false;
418 if ( aNewProfile->ImportFromFile( aFile, &anIsRead ) )
420 aCreatedProfiles.Append( aNewProfile );
421 aNewProfile.Nullify();
425 theBadProfilesIds.Append( aProfileId );
429 if ( !aNewProfile.IsNull() )
430 aNewProfile->Remove();
435 for ( int i = 1, n = aCreatedProfiles.Length(); i <= n ; ++i )
437 Handle(HYDROData_Profile) aProfile = aCreatedProfiles.Value( i );
439 QString aProfileName = HYDROData_Tool::GenerateObjectName( theDoc, "Profile" );
440 aProfile->SetName( aProfileName );
442 aProfile->SetFilePath( theFileName );
444 aProfile->SetBorderColor( HYDROData_Profile::DefaultBorderColor() );
447 return aCreatedProfiles.Length();
450 bool HYDROData_Profile::ImportFromFile( const TCollection_AsciiString& theFileName,
456 // Try to open the file
457 OSD_File aFile( theFileName );
458 if ( !aFile.IsReadable() )
461 aFile.Open( OSD_ReadOnly, OSD_Protection() );
462 if ( !aFile.IsOpen() )
465 bool aRes = ImportFromFile( aFile, theIsRead );
473 SetFilePath( theFileName );
479 bool HYDROData_Profile::ImportFromFile( OSD_File& theFile,
485 if ( !theFile.IsOpen() )
490 bool anIsParametric = false;
491 bool anIsGeoref = false;
493 HYDROData_ProfileUZ::PointsList aPointsUZ;
494 ProfilePoints aPointsXYZ;
496 double aPrevVal = -DBL_MAX;
497 while ( !theFile.IsAtEnd() )
499 Standard_Integer aNbRead = 0;
500 TCollection_AsciiString aLine;
501 theFile.ReadLine( aLine, 1024, aNbRead );
503 aLine.LeftAdjust(); aLine.RightAdjust();
504 if ( aLine.IsEmpty() )
506 if ( !anIsParametric && !anIsGeoref )
507 continue; // Definition is not started yet
509 break; // Next profile started
512 // Set flag of read status to true
516 TCollection_AsciiString aValX = aLine.Token( " \t", 1 );
517 TCollection_AsciiString aValY = aLine.Token( " \t", 2 );
518 TCollection_AsciiString aValZ = aLine.Token( " \t", 3 );
520 if ( aValX.IsEmpty() || !aValX.IsRealValue() ||
521 aValY.IsEmpty() || !aValY.IsRealValue() )
527 if ( !anIsParametric && !anIsGeoref )
529 anIsParametric = aValZ.IsEmpty();
530 anIsGeoref = !aValZ.IsEmpty();
533 double aCoordX = aValX.RealValue();
534 double aCoordY = aValY.RealValue();
536 if ( boost::math::isnan( aCoordX ) || boost::math::isinf( aCoordX ) ||
537 boost::math::isnan( aCoordY ) || boost::math::isinf( aCoordY ) )
540 if ( anIsParametric )
542 if ( aCoordX < aPrevVal )
544 // Move back readed line
545 theFile.Seek( -( aNbRead + 1 ), OSD_FromHere );
549 HYDROData_ProfileUZ::Point aPoint( aCoordX, aCoordY );
550 aPointsUZ.Append( aPoint );
556 if ( aValZ.IsEmpty() || !aValZ.IsRealValue() )
562 double aCoordZ = aValZ.RealValue();
563 if ( boost::math::isnan( aCoordZ ) || boost::math::isinf( aCoordZ ) )
566 ProfilePoint aPoint( aCoordX, aCoordY, aCoordZ );
567 aPointsXYZ.Append( aPoint );
571 aRes = aRes && ( anIsParametric && !aPointsUZ.IsEmpty() ||
572 anIsGeoref && !aPointsXYZ.IsEmpty() );
575 // Update profile points
576 if ( anIsParametric )
578 SetParametricPoints( aPointsUZ );
580 else if ( anIsGeoref )
582 SetProfilePoints( aPointsXYZ );