X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_DTM.cxx;h=544dd2e53184269221fe352cacc1f099c5b7fb0f;hb=f9d37ee66fa46871478d806faa54de237225d3c6;hp=384f672a1348247ef936ac23b5f9523756fb6397;hpb=5124dac22315ff6a5e6cce6509a5f86ea15e1b78;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_DTM.cxx b/src/HYDROData/HYDROData_DTM.cxx index 384f672a..544dd2e5 100644 --- a/src/HYDROData/HYDROData_DTM.cxx +++ b/src/HYDROData/HYDROData_DTM.cxx @@ -18,18 +18,25 @@ #include #include #include +#include #include #include #include +#include +#include #include +#include +#include +#include +#include #include IMPLEMENT_STANDARD_HANDLE( HYDROData_DTM, HYDROData_Bathymetry ) IMPLEMENT_STANDARD_RTTIEXT( HYDROData_DTM, HYDROData_Bathymetry ) -HYDROData_DTM::CurveUZ::CurveUZ( double theXCurv ) - : myXcurv( theXCurv ) +HYDROData_DTM::CurveUZ::CurveUZ( double theXCurv, const gp_Vec2d& theProfileDir ) + : myXcurv( theXCurv ), myProfileDir( theProfileDir ) { } @@ -42,9 +49,14 @@ double HYDROData_DTM::CurveUZ::Xcurv() const return myXcurv; } +gp_Vec2d HYDROData_DTM::CurveUZ::ProfileDir() const +{ + return myProfileDir; +} + HYDROData_DTM::CurveUZ HYDROData_DTM::CurveUZ::operator + ( const CurveUZ& c ) const { - HYDROData_DTM::CurveUZ res( Xcurv() + c.Xcurv() ); + HYDROData_DTM::CurveUZ res( Xcurv() + c.Xcurv(), ProfileDir() + c.ProfileDir() ); size_t n = size(); res.reserve( n ); for( int i=0; iSetValue( (int)i, aPnt ); + tangents.SetValue( (int)i, aVec ); + flags->SetValue( (int)i, Standard_True ); + } + + GeomAPI_Interpolate anInterpolator( points, Standard_False, Standard_False ); + anInterpolator.Load( tangents, flags ); + anInterpolator.Perform(); + if( anInterpolator.IsDone() ) + { + aCurve = anInterpolator.Curve(); + return BRepBuilderAPI_MakeEdge( aCurve ).Edge(); + } + else + return TopoDS_Edge(); +} + HYDROData_DTM::HYDROData_DTM() @@ -82,8 +145,73 @@ HYDROData_DTM::~HYDROData_DTM() { } +HYDROData_SequenceOfObjects HYDROData_DTM::GetProfiles() const +{ + return GetReferenceObjects( DataTag_Profiles ); +} + +void HYDROData_DTM::SetProfiles( const HYDROData_SequenceOfObjects& theProfiles ) +{ + SetReferenceObjects( theProfiles, DataTag_Profiles ); +} + +double HYDROData_DTM::GetDDZ() const +{ + return GetDouble( DataTag_DDZ ); +} + +void HYDROData_DTM::SetDDZ( double theDDZ ) +{ + SetDouble( DataTag_DDZ, theDDZ ); +} + +double HYDROData_DTM::GetSpatialStep() const +{ + return GetDouble( DataTag_SpatialStep ); +} + +void HYDROData_DTM::SetSpatialStep( double theSpatialStep ) +{ + SetDouble( DataTag_SpatialStep, theSpatialStep ); +} + +void HYDROData_DTM::Update() +{ + HYDROData_SequenceOfObjects objs = GetProfiles(); + int aLower = objs.Lower(), anUpper = objs.Upper(); + size_t n = anUpper-aLower+1; + + std::vector profiles; + profiles.reserve( n ); + for( int i=aLower; i<=anUpper; i++ ) + { + Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( objs.Value( i ) ); + if( !aProfile.IsNull() ) + profiles.push_back( aProfile ); + } + + double ddz = GetDDZ(); + double step = GetSpatialStep(); + const double EPS = 1E-3; + AltitudePoints points; + + myLeft.clear(); + myRight.clear(); + if( ddz>EPS && step>EPS ) + points = Interpolate( profiles, ddz, step, &myLeft, &myRight ); + SetAltitudePoints( points ); +} + + + -void GetProperties( const Handle_HYDROData_Profile& theProfile, + + + + + + +void HYDROData_DTM::GetProperties( const Handle_HYDROData_Profile& theProfile, gp_Pnt& theLowestPoint, gp_Vec2d& theDir, bool isNormalDir, double& theZMin, double& theZMax ) @@ -99,6 +227,20 @@ void GetProperties( const Handle_HYDROData_Profile& theProfile, theDir = gp_Vec2d( -y, x ); else theDir = gp_Vec2d( x, y ); + + HYDROData_Profile::ProfilePoints points = theProfile->GetProfilePoints(); + int lo = points.Lower(); + int up = points.Upper(); + theZMin = std::numeric_limits::max(); + theZMax = -theZMin; + for( int i=lo; i<=up; i++ ) + { + double z = points.Value( i ).Z(); + if( z>theZMax ) + theZMax = z; + if( zValue( (Standard_Integer)i ); + Geom2dAPI_ProjectPointOnCurve aProject( aPnt, aResult ); + Standard_Real aParam = aProject.LowerDistanceParameter(); + double aDistance = GCPnts_AbscissaPoint::Length( anAdaptor, aParamFirst, aParam ); + theDistances.push_back( aDistance ); + } } return aResult; } std::vector HYDROData_DTM::ProfileToParametric( const Handle_HYDROData_Profile& theProfile, - double& theUMin, double& theUMax ) + double& theUMin, double& theUMax, gp_Vec2d& theDir ) { std::vector curves; // Transformation of the coordinate systems gp_Pnt aLowest; - gp_Vec2d aDir; double zmin, zmax; - GetProperties( theProfile, aLowest, aDir, false, zmin, zmax ); + GetProperties( theProfile, aLowest, theDir, false, zmin, zmax ); gp_Ax3 aStd3d( gp_Pnt( 0, 0, 0 ), gp_Dir( 0, 0, 1 ), gp_Dir( 1, 0, 0 ) ); - gp_Ax3 aLocal( aLowest, gp_Dir( 0, 0, 1 ), gp_Dir( aDir.X(), aDir.Y(), 0 ) ); + gp_Ax3 aLocal( aLowest, gp_Dir( 0, 0, 1 ), gp_Dir( theDir.X(), theDir.Y(), 0 ) ); gp_Trsf aTransf; aTransf.SetTransformation( aStd3d, aLocal ); @@ -238,26 +393,14 @@ std::vector HYDROData_DTM::ProfileToParametric( } -double CalcGC( const std::vector& intersections ) -{ - double u = 0; - size_t n = intersections.size(); - for( size_t i = 0; i < n; i++ ) - { - u += intersections[i].X(); - } - u /= n; - return u; -} - -double CalcWidth( const std::vector& intersections ) +bool CalcMidWidth( const std::vector& intersections, double& theMid, double& theWid ) { double umin = std::numeric_limits::max(), umax = -umin; size_t n = intersections.size(); if( n <= 1 ) - return 0; + return false; for( size_t i = 0; i < n; i++ ) { @@ -267,7 +410,9 @@ double CalcWidth( const std::vector& intersections ) if( u>umax ) umax = u; } - return umax-umin; + theMid = ( umin+umax )/2; + theWid = umax-umin; + return true; } void HYDROData_DTM::ProfileDiscretization( const Handle_HYDROData_Profile& theProfile, @@ -278,9 +423,11 @@ void HYDROData_DTM::ProfileDiscretization( const Handle_HYDROData_Profile& thePr { double aDblMax = std::numeric_limits::max(), aUMin = aDblMax, - aUMax = -aUMin; + aUMax = -aUMin, + aVMax = 1000000; - std::vector curves = ProfileToParametric( theProfile, aUMin, aUMax ); + gp_Vec2d aProfileDir; + std::vector curves = ProfileToParametric( theProfile, aUMin, aUMax, aProfileDir ); size_t n = curves.size(); if( n==0 ) @@ -291,18 +438,18 @@ void HYDROData_DTM::ProfileDiscretization( const Handle_HYDROData_Profile& thePr curves[0]->D0( curves[0]->FirstParameter(), aFirst ); curves[n-1]->D0( curves[n-1]->LastParameter(), aLast ); Handle(Geom2d_Line) aV1 = new Geom2d_Line( aFirst, gp_Dir2d( 0, 1 ) ); - Handle(Geom2d_TrimmedCurve) aT1 = new Geom2d_TrimmedCurve( aV1, 0.0, aDblMax ); + Handle(Geom2d_TrimmedCurve) aT1 = new Geom2d_TrimmedCurve( aV1, 0.0, aVMax ); Handle(Geom2d_Line) aV2 = new Geom2d_Line( aLast, gp_Dir2d( 0, 1 ) ); - Handle(Geom2d_TrimmedCurve) aT2 = new Geom2d_TrimmedCurve( aV2, 0.0, aDblMax ); + Handle(Geom2d_TrimmedCurve) aT2 = new Geom2d_TrimmedCurve( aV2, 0.0, aVMax ); curves.push_back( aT1 ); curves.push_back( aT2 ); int psize = ( int )( ( theMaxZ-theMinZ ) / theDDZ + 1 ); - theMidPointCurve = CurveUZ( theXCurv ); + theMidPointCurve = CurveUZ( theXCurv, aProfileDir ); theMidPointCurve.reserve( psize ); - theWidthCurve = CurveUZ( theXCurv ); + theWidthCurve = CurveUZ( theXCurv, aProfileDir ); theWidthCurve.reserve( psize ); n = curves.size(); @@ -315,19 +462,21 @@ void HYDROData_DTM::ProfileDiscretization( const Handle_HYDROData_Profile& thePr { Handle_Geom2d_Curve aCurve = curves[i]; Geom2dAPI_InterCurveCurve anIntersect( aCurve, aLine, theTolerance ); - for( int k=0, m=anIntersect.NbPoints(); k= 2 ) { - double u_mid = CalcGC( intersections ); + double u_mid, u_wid; + if( !CalcMidWidth( intersections, u_mid, u_wid ) ) + continue; + PointUZ p_mid; p_mid.U = u_mid; p_mid.Z = z; theMidPointCurve.push_back( p_mid ); - double u_wid = CalcWidth( intersections ); PointUZ p_wid; p_wid.U = u_wid; p_wid.Z = z; @@ -354,11 +503,75 @@ void HYDROData_DTM::Interpolate( const CurveUZ& theCurveA, const CurveUZ& theCur if( isAddSecond ) theInterpolation.push_back( theCurveB ); } - -void HYDROData_DTM::CurveTo3d( const CurveUZ& theMidCurve, const CurveUZ& theWidthCurve, - AltitudePoints& thePoints ) +#include +void HYDROData_DTM::CurveTo3D( const Handle_Geom2d_BSplineCurve& theHydraulicAxis, + const CurveUZ& theMidCurve, const CurveUZ& theWidthCurve, + AltitudePoints& thePoints, + Bank* theLeft, Bank* theRight, double dz ) { - //TODO + Geom2dAdaptor_Curve anAdaptor( theHydraulicAxis ); + TopoDS_Edge E2d = BRepLib_MakeEdge2d(theHydraulicAxis).Edge(); + GCPnts_AbscissaPoint ap( anAdaptor, theMidCurve.Xcurv(), anAdaptor.FirstParameter() ); + double aParam = ap.Parameter(); + + gp_Pnt2d point; + anAdaptor.D0( aParam, point ); + gp_Vec2d profile_dir = theMidCurve.ProfileDir(); + gp_Dir tangent_n( -profile_dir.Y(), profile_dir.X(), dz ); + profile_dir.Normalize(); + + size_t n = theMidCurve.size(); + double min_param = 1E+15; + double max_param = -1E+15; + double z1, z2; + for( size_t i=0; i max_param ) + { + max_param = param1; + z2 = z; + } + if( param2 > max_param ) + { + max_param = param2; + z2 = z; + } + + AltitudePoint p3d_1( p1.X(), p1.Y(), z ), p3d_2( p2.X(), p2.Y(), z ); + thePoints.push_back( p3d_1 ); + thePoints.push_back( p3d_2 ); + } + + if( theLeft ) + { + gp_Pnt2d left2d = point.Translated( min_param * profile_dir ); + gp_Pnt left( left2d.X(), left2d.Y(), z1 ); + theLeft->push_back( left, tangent_n ); + } + if( theRight ) + { + gp_Pnt2d right2d = point.Translated( max_param * profile_dir ); + gp_Pnt right( right2d.X(), right2d.Y(), z2 ); + theRight->push_back( right, tangent_n ); + } } inline double max( double a, double b ) @@ -369,12 +582,16 @@ inline double max( double a, double b ) return b; } -void HYDROData_DTM::Interpolate( const Handle_HYDROData_Profile& theProfileA, - double theXCurvA, - const Handle_HYDROData_Profile& theProfileB, - double theXCurvB, - double theDDZ, int theNbSteps, bool isAddSecond, - AltitudePoints& thePoints ) +#include + +HYDROData_Bathymetry::AltitudePoints HYDROData_DTM::Interpolate + ( const Handle_Geom2d_BSplineCurve& theHydraulicAxis, + const Handle_HYDROData_Profile& theProfileA, + double theXCurvA, + const Handle_HYDROData_Profile& theProfileB, + double theXCurvB, + double theDDZ, int theNbSteps, bool isAddSecond, + Bank* theLeft, Bank* theRight ) { double zminA, zmaxA, zminB, zmaxB; gp_Pnt lowestA, lowestB; @@ -383,11 +600,13 @@ void HYDROData_DTM::Interpolate( const Handle_HYDROData_Profile& theProfileA, GetProperties( theProfileA, lowestA, dirA, false, zminA, zmaxA ); GetProperties( theProfileB, lowestB, dirB, false, zminB, zmaxB ); + double dz = zminB - zminA; + double zmin = max( zminA, zminB ); double zmax = max( zmaxA, zmaxB ); - CurveUZ midA(0), midB(0); - CurveUZ widA(0), widB(0); + CurveUZ midA(0, gp_Vec2d()), midB(0, gp_Vec2d()); + CurveUZ widA(0, gp_Vec2d()), widB(0, gp_Vec2d()); ProfileDiscretization( theProfileA, theXCurvA, zmin, zmax, theDDZ, midA, widA ); ProfileDiscretization( theProfileB, theXCurvB, zmin, zmax, theDDZ, midB, widB ); @@ -396,29 +615,67 @@ void HYDROData_DTM::Interpolate( const Handle_HYDROData_Profile& theProfileA, Interpolate( midA, midB, theNbSteps, mid, isAddSecond ); Interpolate( widA, widB, theNbSteps, wid, isAddSecond ); - size_t q = mid.size(); - for( size_t i=0; i0 ? 2*mid[0].size() : 1; + AltitudePoints points; + points.reserve( p*q ); + for( size_t i=0; imyPoints.size() - 1; i++) + WM.Add(BRepLib_MakeEdge(theLeft->myPoints[i], theLeft->myPoints[i+1]).Edge()); + TopoDS_Wire W = WM.Wire(); + return points; } -void HYDROData_DTM::Interpolate( const std::vector& theProfiles, - double theDDZ, double theSpatialStep, AltitudePoints& thePoints ) +HYDROData_Bathymetry::AltitudePoints HYDROData_DTM::Interpolate + ( const std::vector& theProfiles, + double theDDZ, double theSpatialStep, + Bank* theLeft, + Bank* theRight ) { + AltitudePoints points; size_t n = theProfiles.size(); if( n<=1 ) - return; + return points; std::vector distances; Handle_Geom2d_BSplineCurve aHydraulicAxis = CreateHydraulicAxis( theProfiles, distances ); if( aHydraulicAxis.IsNull() ) - return; + return points; + int aNbStepsComplete = 0; + for( size_t i=0, n1=n-1; ireserve( aNbStepsComplete ); + if( theRight ) + theRight->reserve( aNbStepsComplete ); + for( size_t i=0, n1=n-1; i