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"
8 #include <HYDROData_Tool.h>
9 #include <BRep_Tool.hxx>
11 #include <BRepBuilderAPI_MakeEdge.hxx>
12 #include <BRepBuilderAPI_MakeFace.hxx>
13 #include <BRepBuilderAPI_MakeWire.hxx>
15 #include <Extrema_ExtElC.hxx>
17 #include <GeomAPI_ProjectPointOnCurve.hxx>
21 #include <Precision.hxx>
23 #include <TopExp_Explorer.hxx>
26 #include <TopoDS_Wire.hxx>
27 #include <TopoDS_Edge.hxx>
29 #include <TopTools_SequenceOfShape.hxx>
31 #include <Geom_Line.hxx>
33 #include <QStringList>
36 #include <BRepTools.hxx>
37 #include <BRep_Builder.hxx>
38 #include <BRepBuilderAPI_MakeVertex.hxx>
40 IMPLEMENT_STANDARD_HANDLE(HYDROData_StreamAltitude, HYDROData_IAltitudeObject)
41 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_StreamAltitude, HYDROData_IAltitudeObject)
43 HYDROData_StreamAltitude::HYDROData_StreamAltitude()
44 : HYDROData_IAltitudeObject()
48 HYDROData_StreamAltitude::~HYDROData_StreamAltitude()
52 Standard_Real getAltitudeFromProfile( const Handle(HYDROData_Profile)& theProfile,
53 const Standard_Real& theLeftDist,
54 const Standard_Real& theRightDist )
56 Standard_Real aResAlt = 0.0;
58 gp_XY aFirstPoint, aLastPoint;
59 if ( !theProfile->GetLeftPoint( aFirstPoint, false ) ||
60 !theProfile->GetRightPoint( aLastPoint, false ) )
63 gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
64 gp_Pnt aPnt2( aLastPoint.X(), aLastPoint.Y(), 0 );
66 Standard_Real aProfileDist = aPnt1.Distance( aPnt2 );
68 Standard_Real aCoeff = aProfileDist / ( theLeftDist + theRightDist );
70 gp_Pnt anIntPoint( aPnt1.XYZ() + ( aCoeff * theLeftDist ) * gp_Dir( gp_Vec( aPnt1, aPnt2 ) ).XYZ() );
72 gp_Lin aPointLine( anIntPoint, gp::DZ() );
76 HYDROData_Profile::ProfilePoints aProfilePoints = theProfile->GetProfilePoints( false );
77 for ( int i = 1, n = aProfilePoints.Length(); i <= n; ++i )
79 gp_Pnt aProfPoint( aProfilePoints.Value( i ) );
81 Standard_Real aDist = aPointLine.Distance( aProfPoint );
82 if ( aDist <= gp::Resolution() )
84 // We found the intersected point
85 aResAlt = aProfPoint.Z();
89 gp_Lin aNormal = aPointLine.Normal( aProfPoint );
92 aPrevNormal = aNormal;
93 aPrevPoint = aProfPoint;
97 if ( aPrevNormal.Direction().Dot( aNormal.Direction() ) < 0 )
99 // We found the intersected edge
100 gp_Lin anEdgeLine( aPrevPoint, gp_Dir( gp_Vec( aPrevPoint, aProfPoint ) ) );
102 Extrema_ExtElC anExtrema( aPointLine, anEdgeLine, Precision::Angular() );
103 if ( !anExtrema.IsParallel() )
105 Extrema_POnCurv aFirstPnt, aSecPnt;
106 anExtrema.Points( 1, aFirstPnt, aSecPnt );
108 const gp_Pnt& anIntPnt = aSecPnt.Value();
109 aResAlt = anIntPnt.Z();
115 aPrevNormal = aNormal;
116 aPrevPoint = aProfPoint;
122 bool HYDROData_StreamAltitude::getBoundaryProfilesForPoint(
123 const gp_XY& thePoint,
124 Handle(HYDROData_Profile)& theLeftProfile,
125 Handle(HYDROData_Profile)& theRightProfile ) const
127 Handle(HYDROData_Stream) aStream =
128 Handle(HYDROData_Stream)::DownCast( GetFatherObject() );
129 if ( aStream.IsNull() )
132 HYDROData_SequenceOfObjects aStreamProfiles = aStream->GetProfiles();
133 if ( aStreamProfiles.Length() < 2 )
136 Handle(HYDROData_Profile) aPrevProfile;
137 gp_Pnt aPrevPnt1, aPrevPnt2;
138 for ( int i = 1, n = aStreamProfiles.Length(); i <= n; ++i )
140 Handle(HYDROData_Profile) aProfile =
141 Handle(HYDROData_Profile)::DownCast( aStreamProfiles.Value( i ) );
142 if ( aProfile.IsNull() )
145 gp_XY aFirstPoint, aLastPoint;
146 if ( !aProfile->GetLeftPoint( aFirstPoint, false ) ||
147 !aProfile->GetRightPoint( aLastPoint, false ) )
150 gp_Pnt aPnt1( aFirstPoint.X(), aFirstPoint.Y(), 0 );
151 gp_Pnt aPnt2( aLastPoint.X(), aLastPoint.Y(), 0 );
153 if ( !aPrevProfile.IsNull() )
155 BRepBuilderAPI_MakeEdge aLeftMakeEdge( aPrevPnt1, aPrevPnt2 );
156 BRepBuilderAPI_MakeEdge aBotMakeEdge( aPrevPnt2, aPnt2 );
157 BRepBuilderAPI_MakeEdge aRightMakeEdge( aPnt2, aPnt1 );
158 BRepBuilderAPI_MakeEdge aTopMakeEdge( aPnt1, aPrevPnt1 );
160 BRepBuilderAPI_MakeWire aMakeWire( aLeftMakeEdge.Edge(), aBotMakeEdge.Edge(),
161 aRightMakeEdge.Edge(), aTopMakeEdge.Edge() );
163 BRepBuilderAPI_MakeFace aMakeFace( aMakeWire.Wire() );
165 TopoDS_Face aProfilesFace = aMakeFace.Face();
167 TopoDS_Compound aCmp;
169 aBB.MakeCompound(aCmp);
170 aBB.Add(aCmp, aProfilesFace);
171 gp_Pnt aPnt (thePoint.X(), thePoint.Y(), 0.);
172 BRepBuilderAPI_MakeVertex aMk(aPnt);
173 aBB.Add(aCmp, aMk.Vertex());
174 BRepTools::Write(aCmp, "ProfileFace.brep");
177 TopAbs_State aPointState = HYDROData_Tool::ComputePointState(thePoint, aProfilesFace);
180 cout << "Point status is = " << aPointState <<endl;
182 if ( aPointState != TopAbs_OUT )
184 theLeftProfile = aPrevProfile;
185 theRightProfile = aProfile;
190 aPrevProfile = aProfile;
195 return !theLeftProfile.IsNull() && !theRightProfile.IsNull();
198 double HYDROData_StreamAltitude::GetAltitudeForPoint( const gp_XY& thePoint ) const
200 double aResAltitude = GetInvalidAltitude();
202 Handle(HYDROData_Stream) aStream =
203 Handle(HYDROData_Stream)::DownCast( GetFatherObject() );
204 if ( aStream.IsNull() )
207 TopoDS_Shape aStreamShape = aStream->GetTopShape();
208 if ( aStreamShape.IsNull() )
211 TopExp_Explorer aStreamFaceExp( aStreamShape, TopAbs_FACE );
212 if ( !aStreamFaceExp.More() )
215 // Get only face because of 2d profile wires is in compound
216 TopoDS_Face aStreamFace = TopoDS::Face( aStreamFaceExp.Current() );
218 // Check if point is inside of stream presentation
219 TopAbs_State aPointState = HYDROData_Tool::ComputePointState(thePoint, aStreamFace);
222 cout << "Point status is = " << aPointState <<endl;
223 TopoDS_Compound aCmp;
225 aBB.MakeCompound(aCmp);
226 aBB.Add(aCmp, aStreamFace);
227 gp_Pnt aPnt (thePoint.X(), thePoint.Y(), 0.);
228 BRepBuilderAPI_MakeVertex aMk(aPnt);
229 aBB.Add(aCmp, aMk.Vertex());
230 BRepTools::Write(aCmp, "FCL2d.brep");
232 if ( aPointState == TopAbs_OUT )
235 // Find the two profiles between which the point is lies
236 Handle(HYDROData_Profile) aLeftProfile, aRightProfile;
237 if ( !getBoundaryProfilesForPoint( thePoint, aLeftProfile, aRightProfile ) )
240 // Find the projections of point to borders of stream
241 gp_XYZ aPointToTest( thePoint.X(), thePoint.Y(), 0.0 );
243 TopoDS_Edge aStreamLeftEdge = TopoDS::Edge( aStream->GetLeftShape() );
244 TopoDS_Edge aStreamRightEdge = TopoDS::Edge( aStream->GetRightShape() );
246 Standard_Real aFirst = 0.0, aLast = 0.0;
247 Handle(Geom_Curve) anEdgeLeftCurve = BRep_Tool::Curve( aStreamLeftEdge, aFirst, aLast );
248 Handle(Geom_Curve) anEdgeRightCurve = BRep_Tool::Curve( aStreamRightEdge, aFirst, aLast );
250 GeomAPI_ProjectPointOnCurve aLeftProject( aPointToTest, anEdgeLeftCurve );
251 GeomAPI_ProjectPointOnCurve aRightProject( aPointToTest, anEdgeRightCurve );
253 Standard_Real aLeftDist = aLeftProject.LowerDistance();
254 Standard_Real aRightDist = aRightProject.LowerDistance();
256 // Find the altitude in profiles
257 Standard_Real aLeftAlt = getAltitudeFromProfile( aLeftProfile, aLeftDist, aRightDist );
258 Standard_Real aRightAlt = getAltitudeFromProfile( aRightProfile, aLeftDist, aRightDist );
260 // Interpolate altitudes
261 // Left profile line ( the segment between the firts and the last profile point )
262 HYDROData_Profile::ProfilePoints aLeftProfilePoints = aLeftProfile->GetProfilePoints( false );
263 gp_Pnt aLeftProfileP1( aLeftProfilePoints.First() );
264 aLeftProfileP1.SetZ( 0 );
265 gp_Pnt aLeftProfileP2( aLeftProfilePoints.Last() );
266 aLeftProfileP2.SetZ( 0 );
267 gp_Vec aLeftProfileVec( aLeftProfileP1, aLeftProfileP2 );
268 Handle(Geom_Line) aLeftProfileLine = new Geom_Line( gp_Ax1( aLeftProfileP1, aLeftProfileVec ) );
269 // Right profile line
270 HYDROData_Profile::ProfilePoints aRightProfilePoints = aRightProfile->GetProfilePoints( false );
271 gp_Pnt aRightProfileP1( aRightProfilePoints.First() );
272 aRightProfileP1.SetZ( 0 );
273 gp_Pnt aRightProfileP2( aRightProfilePoints.Last() );
274 aRightProfileP2.SetZ( 0 );
275 gp_Vec aRightProfileVec( aRightProfileP1, aRightProfileP2 );
276 Handle(Geom_Line) aRightProfileLine = new Geom_Line( gp_Ax1( aRightProfileP1, aRightProfileVec ) );
277 // The point projections on the left and right profiles
278 GeomAPI_ProjectPointOnCurve aLeftProfileProject( aPointToTest, aLeftProfileLine );
279 GeomAPI_ProjectPointOnCurve aRightProfileProject( aPointToTest, aRightProfileLine );
280 // The point distance to the left and right profiles
281 Standard_Real aLeftProfileDist = aLeftProfileProject.LowerDistance();
282 Standard_Real aRightProfileDist = aRightProfileProject.LowerDistance();
284 Standard_Real aFirstCoeff = aLeftProfileDist / ( aLeftProfileDist + aRightProfileDist );
285 Standard_Real aSecCoeff = aRightProfileDist / ( aLeftProfileDist + aRightProfileDist );
287 aResAltitude = aLeftAlt * ( 1 - aFirstCoeff ) + aRightAlt * ( 1 - aSecCoeff );