2 #include "HYDROData_StreamAltitude.h"
4 #include "HYDROData_Document.h"
5 #include "HYDROData_Profile.h"
6 #include "HYDROData_Stream.h"
7 #include "HYDROData_ShapesTool.h"
9 #include <BRep_Tool.hxx>
11 #include <BRepTopAdaptor_FClass2d.hxx>
13 #include <BRepBuilderAPI_MakeEdge.hxx>
14 #include <BRepBuilderAPI_MakeFace.hxx>
15 #include <BRepBuilderAPI_MakeWire.hxx>
17 #include <Extrema_ExtElC.hxx>
19 #include <GeomAPI_ProjectPointOnCurve.hxx>
23 #include <Precision.hxx>
25 #include <TopExp_Explorer.hxx>
28 #include <TopoDS_Wire.hxx>
29 #include <TopoDS_Edge.hxx>
31 #include <TopTools_SequenceOfShape.hxx>
33 #include <QStringList>
35 IMPLEMENT_STANDARD_HANDLE(HYDROData_StreamAltitude, HYDROData_IAltitudeObject)
36 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_StreamAltitude, HYDROData_IAltitudeObject)
38 HYDROData_StreamAltitude::HYDROData_StreamAltitude()
39 : HYDROData_IAltitudeObject()
43 HYDROData_StreamAltitude::~HYDROData_StreamAltitude()
47 QStringList HYDROData_StreamAltitude::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
49 QStringList aResList = dumpObjectCreation( theTreatedObjects );
50 QString aName = GetObjPyName();
54 aResList << QString( "" );
55 aResList << QString( "%1.Update();" ).arg( aName );
56 aResList << QString( "" );
61 Standard_Real getAltitudeFromProfile( const Handle(HYDROData_Profile)& theProfile,
62 const Standard_Real& theLeftDist,
63 const Standard_Real& theRightDist )
65 Standard_Real aResAlt = 0.0;
67 gp_XY aFirstPoint, aLastPoint;
68 if ( !theProfile->GetLeftPoint( aFirstPoint ) ||
69 !theProfile->GetRightPoint( aLastPoint ) )
72 gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
73 gp_Pnt aPnt2( aLastPoint.X(), aLastPoint.Y(), 0 );
75 Standard_Real aProfileDist = aPnt1.Distance( aPnt2 );
77 Standard_Real aCoeff = aProfileDist / ( theLeftDist + theRightDist );
79 gp_Pnt anIntPoint( aPnt1.XYZ() + ( aCoeff * theLeftDist ) * gp_Dir( gp_Vec( aPnt1, aPnt2 ) ).XYZ() );
81 gp_Lin aPointLine( anIntPoint, gp::DZ() );
85 HYDROData_Profile::ProfilePoints aProfilePoints = theProfile->GetProfilePoints();
86 for ( int i = 1, n = aProfilePoints.Length(); i <= n; ++i )
88 gp_Pnt aProfPoint( aProfilePoints.Value( i ) );
90 Standard_Real aDist = aPointLine.Distance( aProfPoint );
91 if ( aDist <= gp::Resolution() )
93 // We found the intersected point
94 aResAlt = aProfPoint.Z();
98 gp_Lin aNormal = aPointLine.Normal( aProfPoint );
101 aPrevNormal = aNormal;
102 aPrevPoint = aProfPoint;
106 if ( aPrevNormal.Direction().Dot( aNormal.Direction() ) < 0 )
108 // We found the intersected edge
109 gp_Lin anEdgeLine( aPrevPoint, gp_Dir( gp_Vec( aPrevPoint, aProfPoint ) ) );
111 Extrema_ExtElC anExtrema( aPointLine, anEdgeLine, Precision::Angular() );
112 if ( !anExtrema.IsParallel() )
114 Extrema_POnCurv aFirstPnt, aSecPnt;
115 anExtrema.Points( 1, aFirstPnt, aSecPnt );
117 const gp_Pnt& anIntPnt = aSecPnt.Value();
118 aResAlt = anIntPnt.Z();
124 aPrevNormal = aNormal;
125 aPrevPoint = aProfPoint;
131 bool HYDROData_StreamAltitude::getBoundaryProfilesForPoint(
132 const gp_XY& thePoint,
133 Handle(HYDROData_Profile)& theLeftProfile,
134 Handle(HYDROData_Profile)& theRightProfile ) const
136 Handle(HYDROData_Stream) aStream =
137 Handle(HYDROData_Stream)::DownCast( GetFatherObject() );
138 if ( aStream.IsNull() )
141 HYDROData_SequenceOfObjects aStreamProfiles = aStream->GetProfiles();
142 if ( aStreamProfiles.Length() < 2 )
145 Handle(HYDROData_Profile) aPrevProfile;
146 gp_Pnt aPrevPnt1, aPrevPnt2;
147 for ( int i = 1, n = aStreamProfiles.Length(); i <= n; ++i )
149 Handle(HYDROData_Profile) aProfile =
150 Handle(HYDROData_Profile)::DownCast( aStreamProfiles.Value( i ) );
151 if ( aProfile.IsNull() )
154 gp_XY aFirstPoint, aLastPoint;
155 if ( !aProfile->GetLeftPoint( aFirstPoint ) || !aProfile->GetRightPoint( aLastPoint ) )
158 gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
159 gp_Pnt aPnt2( aLastPoint.X(), aLastPoint.Y(), 0 );
161 if ( !aPrevProfile.IsNull() )
163 BRepBuilderAPI_MakeEdge aLeftMakeEdge( aPrevPnt1, aPrevPnt2 );
164 BRepBuilderAPI_MakeEdge aBotMakeEdge( aPrevPnt2, aPnt2 );
165 BRepBuilderAPI_MakeEdge aRightMakeEdge( aPnt2, aPnt1 );
166 BRepBuilderAPI_MakeEdge aTopMakeEdge( aPnt1, aPrevPnt1 );
168 BRepBuilderAPI_MakeWire aMakeWire( aLeftMakeEdge.Edge(), aBotMakeEdge.Edge(),
169 aRightMakeEdge.Edge(), aTopMakeEdge.Edge() );
171 BRepBuilderAPI_MakeFace aMakeFace( aMakeWire.Wire() );
173 TopoDS_Face aProfilesFace = aMakeFace.Face();
175 BRepTopAdaptor_FClass2d aClassifier( aProfilesFace, Precision::Confusion() );
176 TopAbs_State aPointState = aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
177 if ( aPointState != TopAbs_OUT )
179 theLeftProfile = aPrevProfile;
180 theRightProfile = aProfile;
185 aPrevProfile = aProfile;
190 return !theLeftProfile.IsNull() && !theRightProfile.IsNull();
193 double HYDROData_StreamAltitude::GetAltitudeForPoint( const gp_XY& thePoint ) const
195 double aResAltitude = GetInvalidAltitude();
197 Handle(HYDROData_Stream) aStream =
198 Handle(HYDROData_Stream)::DownCast( GetFatherObject() );
199 if ( aStream.IsNull() )
202 TopoDS_Shape aStreamShape = aStream->GetTopShape();
203 if ( aStreamShape.IsNull() )
206 TopExp_Explorer aStreamFaceExp( aStreamShape, TopAbs_FACE );
207 if ( !aStreamFaceExp.More() )
210 // Get only face because of 2d profile wires is in compound
211 TopoDS_Face aStreamFace = TopoDS::Face( aStreamFaceExp.Current() );
213 // Check if point is inside of stream presentation
214 BRepTopAdaptor_FClass2d aClassifier( aStreamFace, Precision::Confusion() );
215 TopAbs_State aPointState = aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
216 if ( aPointState == TopAbs_OUT )
219 // Find the two profiles between which the point is lies
220 Handle(HYDROData_Profile) aLeftProfile, aRightProfile;
221 if ( !getBoundaryProfilesForPoint( thePoint, aLeftProfile, aRightProfile ) )
224 // Find the projections of point to borders of stream
225 gp_XYZ aPointToTest( thePoint.X(), thePoint.Y(), 0.0 );
227 TopoDS_Edge aStreamLeftEdge = TopoDS::Edge( aStream->GetLeftShape() );
228 TopoDS_Edge aStreamRightEdge = TopoDS::Edge( aStream->GetRightShape() );
230 Standard_Real aFirst = 0.0, aLast = 0.0;
231 Handle(Geom_Curve) anEdgeLeftCurve = BRep_Tool::Curve( aStreamLeftEdge, aFirst, aLast );
232 Handle(Geom_Curve) anEdgeRightCurve = BRep_Tool::Curve( aStreamRightEdge, aFirst, aLast );
234 GeomAPI_ProjectPointOnCurve aLeftProject( aPointToTest, anEdgeLeftCurve );
235 GeomAPI_ProjectPointOnCurve aRightProject( aPointToTest, anEdgeRightCurve );
237 Standard_Real aLeftDist = aLeftProject.LowerDistance();
238 Standard_Real aRightDist = aRightProject.LowerDistance();
240 // Find the altitude in profiles
241 Standard_Real aLeftAlt = getAltitudeFromProfile( aLeftProfile, aLeftDist, aRightDist );
242 Standard_Real aRightAlt = getAltitudeFromProfile( aRightProfile, aLeftDist, aRightDist );
244 // Interpolate altitudes
245 Standard_Real aFirstCoeff = aLeftDist / ( aLeftDist + aRightDist );
246 Standard_Real aSecCoeff = aRightDist / ( aLeftDist + aRightDist );
248 aResAltitude = aLeftAlt * aFirstCoeff + aRightAlt * aSecCoeff;