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 );
99 // Set a polyline type if it is not default
100 Handle(HYDROData_ProfileUZ) aPrf = GetProfileUZ( false );
101 if ( !aPrf.IsNull() )
103 HYDROData_IPolyline::SectionType aSecType = aPrf->GetSectionType( 0 );
104 if ( aSecType != HYDROData_IPolyline::SECTION_POLYLINE )
106 aResList << QString( "%1.GetProfileUZ().SetSectionType( 0, %2 );" ).arg( aName )
107 .arg( "HYDROData_IPolyline.SECTION_SPLINE" );
111 aResList << QString( "" );
112 aResList << QString( "%1.Update();" ).arg( aName );
113 aResList << QString( "" );
118 TopoDS_Shape HYDROData_Profile::GetTopShape() const
122 gp_XY aFirstPoint, aLastPoint;
123 if ( !GetLeftPoint( aFirstPoint ) || !GetRightPoint( aLastPoint ) )
126 gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
127 gp_Pnt aPnt2( aLastPoint.X(), aLastPoint.Y(), 0 );
129 BRepBuilderAPI_MakeEdge aMakeEdge( aPnt1, aPnt2 );
130 TopoDS_Edge anEdge = aMakeEdge;
132 BRepBuilderAPI_MakeWire aMakeWire( anEdge );
138 TopoDS_Shape HYDROData_Profile::GetShape3D() const
143 void HYDROData_Profile::Update()
145 HYDROData_Object::Update();
148 Handle(HYDROData_ProfileUZ) aProfile = GetProfileUZ( false );
149 if ( !aProfile.IsNull() )
151 ProfilePoints aProfilePoints = GetProfilePoints();
152 HYDROData_IPolyline::SectionType aSectionType = aProfile->GetSectionType( 0 );
154 aWire = HYDROData_PolylineXY::BuildWire( aSectionType, false, aProfilePoints );
159 QColor HYDROData_Profile::DefaultFillingColor()
161 return QColor( Qt::transparent );
164 QColor HYDROData_Profile::DefaultBorderColor()
166 return QColor( Qt::black );
169 QColor HYDROData_Profile::getDefaultFillingColor() const
171 return DefaultFillingColor();
174 QColor HYDROData_Profile::getDefaultBorderColor() const
176 return DefaultBorderColor();
179 bool HYDROData_Profile::IsValid() const
181 gp_XY aFirstPoint, aLastPoint;
182 if ( !GetLeftPoint( aFirstPoint ) || !GetRightPoint( aLastPoint ) )
185 int aNbPoints = NbPoints();
186 return aNbPoints > 1;
189 void HYDROData_Profile::SetLeftPoint( const gp_XY& thePoint )
191 TDF_Label aLabel = myLab.FindChild( DataTag_FirstPoint );
193 Handle(TDataStd_RealArray) anArray;
194 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
195 anArray = TDataStd_RealArray::Set( aLabel, 0, 1 );
197 anArray->SetValue( 0, thePoint.X() );
198 anArray->SetValue( 1, thePoint.Y() );
203 bool HYDROData_Profile::GetLeftPoint( gp_XY& thePoint ) const
205 TDF_Label aLabel = myLab.FindChild( DataTag_FirstPoint, false );
206 if ( aLabel.IsNull() )
209 Handle(TDataStd_RealArray) anArray;
210 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
213 thePoint.SetX( anArray->Value( 0 ) );
214 thePoint.SetY( anArray->Value( 1 ) );
219 void HYDROData_Profile::SetRightPoint( const gp_XY& thePoint )
221 TDF_Label aLabel = myLab.FindChild( DataTag_LastPoint );
223 Handle(TDataStd_RealArray) anArray;
224 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
225 anArray = TDataStd_RealArray::Set( aLabel, 0, 1 );
227 anArray->SetValue( 0, thePoint.X() );
228 anArray->SetValue( 1, thePoint.Y() );
233 bool HYDROData_Profile::GetRightPoint( gp_XY& thePoint ) const
235 TDF_Label aLabel = myLab.FindChild( DataTag_LastPoint, false );
236 if ( aLabel.IsNull() )
239 Handle(TDataStd_RealArray) anArray;
240 if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ) )
243 thePoint.SetX( anArray->Value( 0 ) );
244 thePoint.SetY( anArray->Value( 1 ) );
249 void HYDROData_Profile::Invalidate()
251 TDF_Label aFirstLabel = myLab.FindChild( DataTag_FirstPoint, false );
252 if ( !aFirstLabel.IsNull() )
253 aFirstLabel.ForgetAllAttributes();
255 TDF_Label aLastLabel = myLab.FindChild( DataTag_LastPoint, false );
256 if ( !aLastLabel.IsNull() )
257 aLastLabel.ForgetAllAttributes();
262 Handle(HYDROData_ProfileUZ) HYDROData_Profile::GetProfileUZ( const bool theIsCreate ) const
264 Handle(HYDROData_ProfileUZ) aProfileUZ;
266 TDF_Label aLabel = myLab.FindChild( DataTag_ChildProfileUZ, theIsCreate );
267 if ( aLabel.IsNull() )
270 aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast( HYDROData_Iterator::Object( aLabel ) );
271 if ( aProfileUZ.IsNull() && theIsCreate )
273 aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast(
274 HYDROData_Iterator::CreateObject( aLabel, KIND_PROFILEUZ ) );
280 int HYDROData_Profile::NbPoints() const
282 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
283 return aProfileUZ.IsNull() ? 0 : aProfileUZ->NbPoints();
286 void HYDROData_Profile::RemovePoints()
288 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
289 if ( !aProfileUZ.IsNull() )
291 aProfileUZ->RemoveSections();
296 void HYDROData_Profile::SetParametricPoints( const HYDROData_ProfileUZ::PointsList& thePoints )
300 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
301 for ( int i = 1, n = thePoints.Length(); i <= n ; ++i )
303 const HYDROData_ProfileUZ::Point& aPoint = thePoints.Value( i );
304 aProfileUZ->AddPoint( 0, aPoint );
310 HYDROData_ProfileUZ::PointsList HYDROData_Profile::GetParametricPoints() const
312 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ( false );
313 return aProfileUZ.IsNull() ? HYDROData_ProfileUZ::PointsList() : aProfileUZ->GetPoints();
316 void HYDROData_Profile::SetProfilePoints( const ProfilePoints& thePoints )
319 if ( thePoints.Length() < 2 )
322 gp_XY aFirstPoint, aLastPoint;
324 Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
325 for ( int i = 1, n = thePoints.Length(); i <= n ; ++i )
327 const ProfilePoint& aPoint = thePoints.Value( i );
328 gp_XY aPointXY( aPoint.X(), aPoint.Y() );
331 aFirstPoint = aPointXY;
333 aLastPoint = aPointXY;
335 double aDistance = gp_Pnt2d( aFirstPoint ).Distance( aPointXY );
337 HYDROData_ProfileUZ::Point aParPoint( aDistance, aPoint.Z() );
338 aProfileUZ->AddPoint( 0, aParPoint );
341 SetLeftPoint( aFirstPoint );
342 SetRightPoint( aLastPoint );
345 HYDROData_Profile::ProfilePoints HYDROData_Profile::GetProfilePoints() const
347 ProfilePoints aResPoints;
349 gp_XY aFirstPoint, aLastPoint;
350 if ( !GetLeftPoint( aFirstPoint ) || !GetRightPoint( aLastPoint ) )
353 HYDROData_ProfileUZ::PointsList aParametricPoints = GetParametricPoints();
354 if ( aParametricPoints.Length() < 2 )
357 const HYDROData_ProfileUZ::Point& aFirstParPoint = aParametricPoints.First();
358 const HYDROData_ProfileUZ::Point& aLastParPoint = aParametricPoints.Last();
360 double aGeoDistance = gp_Pnt2d( aFirstPoint ).Distance( aLastPoint );
361 double aParCommonDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aLastParPoint.X(), 0 ) );
363 // Add first point as is
364 aResPoints.Append( ProfilePoint( aFirstPoint.X(), aFirstPoint.Y(), aFirstParPoint.Y() ) );
366 // Compute all other points
367 for ( int i = 2, n = aParametricPoints.Length(); i < n ; ++i )
369 const HYDROData_ProfileUZ::Point& aParPoint = aParametricPoints.Value( i );
371 double aParPointDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aParPoint.X(), 0 ) );
373 double aParLen = ( aParPointDist / aParCommonDist ) * aGeoDistance;
375 double aRatio = aParLen / ( aGeoDistance - aParLen );
377 double aParX = ( aFirstPoint.X() + aRatio * aLastPoint.X() ) / ( 1 + aRatio );
378 double aParY = ( aFirstPoint.Y() + aRatio * aLastPoint.Y() ) / ( 1 + aRatio );
380 ProfilePoint aCompPoint( aParX, aParY, aParPoint.Y() );
381 aResPoints.Append( aCompPoint );
384 // Add last point as is
385 aResPoints.Append( ProfilePoint( aLastPoint.X(), aLastPoint.Y(), aLastParPoint.Y() ) );
390 void HYDROData_Profile::SetFilePath( const TCollection_AsciiString& theFilePath )
392 TDataStd_AsciiString::Set( myLab.FindChild( DataTag_FilePath ), theFilePath );
395 TCollection_AsciiString HYDROData_Profile::GetFilePath() const
397 TCollection_AsciiString aRes;
399 Handle(TDataStd_AsciiString) anAsciiStr;
400 if ( myLab.FindChild( DataTag_FilePath ).FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) )
401 aRes = anAsciiStr->Get();
406 int HYDROData_Profile::ImportFromFile( const Handle(HYDROData_Document)& theDoc,
407 const TCollection_AsciiString& theFileName,
408 NCollection_Sequence<int>& theBadProfilesIds )
410 if ( theDoc.IsNull() || theFileName.IsEmpty() )
413 OSD_File aFile( theFileName );
414 if ( !aFile.IsReadable() )
417 aFile.Open( OSD_ReadOnly, OSD_Protection() );
418 if ( !aFile.IsOpen() )
421 NCollection_Sequence<Handle(HYDROData_Profile)> aCreatedProfiles;
424 Handle(HYDROData_Profile) aNewProfile;
425 for ( ; !aFile.IsAtEnd(); ++aProfileId )
427 if ( aNewProfile.IsNull() )
428 aNewProfile = Handle(HYDROData_Profile)::DownCast( theDoc->CreateObject( KIND_PROFILE ) );
430 bool anIsRead = false;
431 if ( aNewProfile->ImportFromFile( aFile, &anIsRead ) )
433 aCreatedProfiles.Append( aNewProfile );
434 aNewProfile.Nullify();
438 theBadProfilesIds.Append( aProfileId );
442 if ( !aNewProfile.IsNull() )
443 aNewProfile->Remove();
448 for ( int i = 1, n = aCreatedProfiles.Length(); i <= n ; ++i )
450 Handle(HYDROData_Profile) aProfile = aCreatedProfiles.Value( i );
452 QString aProfileName = HYDROData_Tool::GenerateObjectName( theDoc, "Profile" );
453 aProfile->SetName( aProfileName );
455 aProfile->SetFilePath( theFileName );
457 aProfile->SetBorderColor( HYDROData_Profile::DefaultBorderColor() );
460 return aCreatedProfiles.Length();
463 bool HYDROData_Profile::ImportFromFile( const TCollection_AsciiString& theFileName,
469 // Try to open the file
470 OSD_File aFile( theFileName );
471 if ( !aFile.IsReadable() )
474 aFile.Open( OSD_ReadOnly, OSD_Protection() );
475 if ( !aFile.IsOpen() )
478 bool aRes = ImportFromFile( aFile, theIsRead );
486 SetFilePath( theFileName );
492 bool HYDROData_Profile::ImportFromFile( OSD_File& theFile,
498 if ( !theFile.IsOpen() )
503 bool anIsParametric = false;
504 bool anIsGeoref = false;
506 HYDROData_ProfileUZ::PointsList aPointsUZ;
507 ProfilePoints aPointsXYZ;
509 double aPrevVal = -DBL_MAX;
510 while ( !theFile.IsAtEnd() )
512 Standard_Integer aNbRead = 0;
513 TCollection_AsciiString aLine;
514 theFile.ReadLine( aLine, 1024, aNbRead );
516 aLine.LeftAdjust(); aLine.RightAdjust();
517 if ( aLine.IsEmpty() )
519 if ( !anIsParametric && !anIsGeoref )
520 continue; // Definition is not started yet
522 break; // Next profile started
525 // Set flag of read status to true
529 TCollection_AsciiString aValX = aLine.Token( " \t", 1 );
530 TCollection_AsciiString aValY = aLine.Token( " \t", 2 );
531 TCollection_AsciiString aValZ = aLine.Token( " \t", 3 );
533 if ( aValX.IsEmpty() || !aValX.IsRealValue() ||
534 aValY.IsEmpty() || !aValY.IsRealValue() )
540 if ( !anIsParametric && !anIsGeoref )
542 anIsParametric = aValZ.IsEmpty();
543 anIsGeoref = !aValZ.IsEmpty();
546 double aCoordX = aValX.RealValue();
547 double aCoordY = aValY.RealValue();
549 if ( boost::math::isnan( aCoordX ) || boost::math::isinf( aCoordX ) ||
550 boost::math::isnan( aCoordY ) || boost::math::isinf( aCoordY ) )
553 if ( anIsParametric )
555 if ( aCoordX < aPrevVal )
557 // Move back readed line
558 theFile.Seek( -( aNbRead + 1 ), OSD_FromHere );
562 HYDROData_ProfileUZ::Point aPoint( aCoordX, aCoordY );
563 aPointsUZ.Append( aPoint );
569 if ( aValZ.IsEmpty() || !aValZ.IsRealValue() )
575 double aCoordZ = aValZ.RealValue();
576 if ( boost::math::isnan( aCoordZ ) || boost::math::isinf( aCoordZ ) )
579 ProfilePoint aPoint( aCoordX, aCoordY, aCoordZ );
580 aPointsXYZ.Append( aPoint );
584 aRes = aRes && ( anIsParametric && !aPointsUZ.IsEmpty() ||
585 anIsGeoref && !aPointsXYZ.IsEmpty() );
588 // Update profile points
589 if ( anIsParametric )
591 SetParametricPoints( aPointsUZ );
593 else if ( anIsGeoref )
595 SetProfilePoints( aPointsXYZ );