From ff852fa6906c698aea0e95554f1c33e2560b61ef Mon Sep 17 00:00:00 2001 From: adv Date: Fri, 13 Dec 2013 08:38:57 +0000 Subject: [PATCH] Projection of polyline on bathymetry object (Feature #234). --- src/HYDROData/HYDROData_Object.cxx | 20 +++++++- src/HYDROData/HYDROData_Object.h | 2 +- src/HYDROData/HYDROData_Polyline3D.cxx | 69 ++++++++++++++++++++++++-- src/HYDROData/HYDROData_Polyline3D.h | 11 +++- src/HYDROData/HYDROData_ProfileUZ.cxx | 12 ++--- src/HYDROData/HYDROData_ProfileUZ.h | 5 +- src/HYDROGUI/HYDROGUI_Poly3DOp.cxx | 56 ++++++++++++--------- 7 files changed, 134 insertions(+), 41 deletions(-) diff --git a/src/HYDROData/HYDROData_Object.cxx b/src/HYDROData/HYDROData_Object.cxx index 524916fc..ce02f9d9 100644 --- a/src/HYDROData/HYDROData_Object.cxx +++ b/src/HYDROData/HYDROData_Object.cxx @@ -94,12 +94,24 @@ void HYDROData_Object::Update() removeShape3D(); } -void HYDROData_Object::SetBathymetry( const Handle(HYDROData_Bathymetry)& theBathymetry ) +bool HYDROData_Object::SetBathymetry( const Handle(HYDROData_Bathymetry)& theBathymetry ) { + if ( theBathymetry.IsNull() ) + return false; + + Handle(HYDROData_Bathymetry) aPrevBathymetry = GetBathymetry(); + if ( IsEqual( aPrevBathymetry, theBathymetry ) ) + return true; + SetReferenceObject( theBathymetry, DataTag_Bathymetry ); + + // Indicate model of the need to update object SetToUpdate( true ); + + return true; } + Handle(HYDROData_Bathymetry) HYDROData_Object::GetBathymetry() const { return Handle(HYDROData_Bathymetry)::DownCast( @@ -108,7 +120,13 @@ Handle(HYDROData_Bathymetry) HYDROData_Object::GetBathymetry() const void HYDROData_Object::RemoveBathymetry() { + Handle(HYDROData_Bathymetry) aPrevBathymetry = GetBathymetry(); + if ( aPrevBathymetry.IsNull() ) + return; + ClearReferenceObjects( DataTag_Bathymetry ); + + // Indicate model of the need to update object SetToUpdate( true ); } diff --git a/src/HYDROData/HYDROData_Object.h b/src/HYDROData/HYDROData_Object.h index 80746563..949372ca 100644 --- a/src/HYDROData/HYDROData_Object.h +++ b/src/HYDROData/HYDROData_Object.h @@ -84,7 +84,7 @@ public: /** * Set reference bathymetry object for geometry object. */ - HYDRODATA_EXPORT virtual void SetBathymetry( const Handle(HYDROData_Bathymetry)& theBathymetry ); + HYDRODATA_EXPORT virtual bool SetBathymetry( const Handle(HYDROData_Bathymetry)& theBathymetry ); /** * Returns reference bathymetry object of geometry object. diff --git a/src/HYDROData/HYDROData_Polyline3D.cxx b/src/HYDROData/HYDROData_Polyline3D.cxx index 8bff09cb..5cf9287f 100644 --- a/src/HYDROData/HYDROData_Polyline3D.cxx +++ b/src/HYDROData/HYDROData_Polyline3D.cxx @@ -1,6 +1,7 @@ #include "HYDROData_Polyline3D.h" +#include "HYDROData_Bathymetry.h" #include "HYDROData_Document.h" #include "HYDROData_PolylineXY.h" #include "HYDROData_ProfileUZ.h" @@ -76,20 +77,63 @@ TopoDS_Shape HYDROData_Polyline3D::GetShape3D() const return getShape3D(); } +HYDROData_IPolyline::PointsList generateProfileUZPoints( + const Handle(HYDROData_PolylineXY)& thePolyline, + const Handle(HYDROData_Bathymetry)& theBathymetry ) +{ + HYDROData_IPolyline::PointsList aPointsList; + if ( thePolyline.IsNull() || theBathymetry.IsNull() ) + return aPointsList; + + bool anIsSectionClosed = thePolyline->IsClosedSection( 0 ); + HYDROData_IPolyline::SectionType aSectionType = thePolyline->GetSectionType( 0 ); + HYDROData_IPolyline::PointsList aPolylinePoints = thePolyline->GetPoints( 0 ); + if ( aPolylinePoints.IsEmpty() ) + return aPointsList; + + for ( int i = 1, aNbPoints = aPolylinePoints.Size(); i <= aNbPoints; ++i ) + { + const HYDROData_PolylineXY::Point& aSectPoint = aPolylinePoints.Value( i ); + + double aPointDistance = thePolyline->GetDistance( 0, i - 1 ); + double aPointDepth = theBathymetry->GetAltitudeForPoint( aSectPoint ); + + HYDROData_IPolyline::Point anAltitudePoint( aPointDistance, aPointDepth ); + aPointsList.Append( anAltitudePoint ); + } + + return aPointsList; +} + void HYDROData_Polyline3D::Update() { HYDROData_Object::Update(); Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY(); - Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ(); - if ( aPolylineXY.IsNull() || aProfileUZ.IsNull() ) + if ( aPolylineXY.IsNull() ) return; bool anIsSectionClosed = aPolylineXY->IsClosedSection( 0 ); HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 ); HYDROData_IPolyline::PointsList aPolylinePoints = aPolylineXY->GetPoints( 0 ); - HYDROData_IPolyline::PointsList aProfilePoints = aProfileUZ->GetPoints(); - if ( aPolylinePoints.IsEmpty() || aProfilePoints.IsEmpty() ) + if ( aPolylinePoints.IsEmpty() ) + return; + + HYDROData_IPolyline::PointsList aProfilePoints; + + Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ(); + Handle(HYDROData_Bathymetry) aBathymetry = GetBathymetry(); + + if ( !aProfileUZ.IsNull() ) + { + aProfilePoints = aProfileUZ->GetPoints(); + } + else if ( !aBathymetry.IsNull() ) + { + aProfilePoints = generateProfileUZPoints( aPolylineXY, aBathymetry ); + } + + if ( aProfilePoints.IsEmpty() ) return; const HYDROData_IPolyline::Point& aFirstPoint = aPolylinePoints.First(); @@ -113,7 +157,7 @@ void HYDROData_Polyline3D::Update() double aDistance = aPolylineXY->GetDistance( 0, i - 1 ); double aParLen = ( aDistance / aPolylineCommonDist ) * aParCommonDist; - double aDepth = aProfileUZ->GetDepthFromDistance( aParLen ); + double aDepth = HYDROData_ProfileUZ::GetDepthFromDistance( aProfilePoints, aParLen ); Polyline3DPoint aCompPoint( aPolylinePoint.X(), aPolylinePoint.Y(), aDepth ); aResPoints.Append( aCompPoint ); @@ -193,6 +237,9 @@ bool HYDROData_Polyline3D::SetProfileUZ( const Handle(HYDROData_ProfileUZ)& theP SetReferenceObject( theProfile, DataTag_ProfileUZ ); + // Remove the bathymetry, because one altitude object can be presented at time + RemoveBathymetry(); + // Indicate model of the need to update the polyline presentation SetToUpdate( true ); @@ -217,3 +264,15 @@ void HYDROData_Polyline3D::RemoveProfileUZ() SetToUpdate( true ); } + +bool HYDROData_Polyline3D::SetBathymetry( const Handle(HYDROData_Bathymetry)& theBathymetry ) +{ + if ( !HYDROData_Object::SetBathymetry( theBathymetry ) ) + return false; + + // Remove the u,z profile, because one altitude object can be presented at time + RemoveProfileUZ(); + + return true; +} + diff --git a/src/HYDROData/HYDROData_Polyline3D.h b/src/HYDROData/HYDROData_Polyline3D.h index e05cfdb9..f6e883b8 100644 --- a/src/HYDROData/HYDROData_Polyline3D.h +++ b/src/HYDROData/HYDROData_Polyline3D.h @@ -28,8 +28,8 @@ protected: enum DataTag { DataTag_First = HYDROData_Object::DataTag_First + 100, ///< first tag, to reserve - DataTag_PolylineXY, ///< reference hydraulic axis - DataTag_ProfileUZ, ///< reference profiles + DataTag_PolylineXY, ///< reference hydraulic axis + DataTag_ProfileUZ, ///< reference profile }; public: @@ -112,6 +112,13 @@ public: HYDRODATA_EXPORT virtual void RemoveProfileUZ(); + /** + * Set reference bathymetry object for geometry object. + * Reimplemented to remove reference u,z profile. + */ + HYDRODATA_EXPORT virtual bool SetBathymetry( const Handle(HYDROData_Bathymetry)& theBathymetry ); + + protected: /** diff --git a/src/HYDROData/HYDROData_ProfileUZ.cxx b/src/HYDROData/HYDROData_ProfileUZ.cxx index dc82a136..f18e98aa 100755 --- a/src/HYDROData/HYDROData_ProfileUZ.cxx +++ b/src/HYDROData/HYDROData_ProfileUZ.cxx @@ -34,20 +34,20 @@ TopoDS_Shape HYDROData_ProfileUZ::GetShape() return TopoDS_Shape(); } -double HYDROData_ProfileUZ::GetDepthFromDistance( const double& theDistance ) const +double HYDROData_ProfileUZ::GetDepthFromDistance( const PointsList& thePoints, + const double& theDistance ) { double aResDepth = 0.0; - HYDROData_IPolyline::PointsList aPoints = GetPoints(); - int aNbPoints = aPoints.Size(); + int aNbPoints = thePoints.Size(); if ( aNbPoints < 2 ) return aResDepth; double aCompDist = 0.0; - HYDROData_IPolyline::Point aPrevPoint = aPoints.First(); + HYDROData_IPolyline::Point aPrevPoint = thePoints.First(); for ( int i = 2; i <= aNbPoints; ++i ) { - const Point& aCurPoint = aPoints.Value( i ); + const Point& aCurPoint = thePoints.Value( i ); double aPntDist = gp_Pnt2d( aPrevPoint.X(), 0 ).Distance( gp_Pnt2d( aCurPoint.X(), 0 ) ); @@ -55,7 +55,7 @@ double HYDROData_ProfileUZ::GetDepthFromDistance( const double& theDistance ) co if ( theDistance < aCompDist ) { - double aComPntDist = gp_Pnt2d( aPoints.First().X(), 0 ).Distance( gp_Pnt2d( aPrevPoint.X(), 0 ) ); + double aComPntDist = gp_Pnt2d( thePoints.First().X(), 0 ).Distance( gp_Pnt2d( aPrevPoint.X(), 0 ) ); double aFindDist = theDistance - aComPntDist; double aRatio = aFindDist / ( aPntDist - aFindDist ); diff --git a/src/HYDROData/HYDROData_ProfileUZ.h b/src/HYDROData/HYDROData_ProfileUZ.h index c485e944..b982a1d8 100644 --- a/src/HYDROData/HYDROData_ProfileUZ.h +++ b/src/HYDROData/HYDROData_ProfileUZ.h @@ -38,9 +38,10 @@ public: HYDRODATA_EXPORT virtual TopoDS_Shape GetShape(); /** - * Returns the 3D presentation of all points. + * Returns the depth for given distance. */ - HYDRODATA_EXPORT virtual double GetDepthFromDistance( const double& theDistance ) const; + HYDRODATA_EXPORT static double GetDepthFromDistance( const PointsList& thePoints, + const double& theDistance ); /** diff --git a/src/HYDROGUI/HYDROGUI_Poly3DOp.cxx b/src/HYDROGUI/HYDROGUI_Poly3DOp.cxx index 74ea159a..26c9e374 100644 --- a/src/HYDROGUI/HYDROGUI_Poly3DOp.cxx +++ b/src/HYDROGUI/HYDROGUI_Poly3DOp.cxx @@ -77,15 +77,21 @@ void HYDROGUI_Poly3DOp::startOperation() QString aPolyName, aProfileName, aBathName; if( myIsEdit && !myEditedObject.IsNull() ) { - Handle(HYDROData_Entity) aProfile = myEditedObject->GetProfileUZ()->GetFatherObject(); - if( !aProfile.IsNull() ) - aProfileName = aProfile->GetName(); + Handle(HYDROData_ProfileUZ) aProfileUZ = myEditedObject->GetProfileUZ(); + if( !aProfileUZ.IsNull() ) + { + Handle(HYDROData_Entity) aProfile = aProfileUZ->GetFatherObject(); + if ( !aProfile.IsNull() ) + aProfileName = aProfile->GetName(); + } Handle(HYDROData_Entity) aPoly = myEditedObject->GetPolylineXY(); if( !aPoly.IsNull() ) aPolyName = aPoly->GetName(); - //TODO: use bathymetry from data model + Handle(HYDROData_Bathymetry) aBathymetry = myEditedObject->GetBathymetry(); + if( !aBathymetry.IsNull() ) + aBathName = aBathymetry->GetName(); aPanel->setSelectedObjects( aPolyName, aProfileName, aBathName ); } @@ -125,25 +131,14 @@ bool HYDROGUI_Poly3DOp::processApply( int& theUpdateFlags, } } - Handle(HYDROData_Entity) aProfileEnt = - HYDROGUI_Tool::FindObjectByName( module(), aProfileName, KIND_PROFILE ) ; - Handle(HYDROData_Entity) aPolyEnt = - HYDROGUI_Tool::FindObjectByName( module(), aPolyName, KIND_POLYLINEXY ); - Handle(HYDROData_Entity) aBathEnt = - HYDROGUI_Tool::FindObjectByName( module(), aBathName, KIND_BATHYMETRY ); - - if( aPolyEnt.IsNull() || ( aPolyEnt.IsNull() && aBathEnt.IsNull() ) ) - return false; - - Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( aProfileEnt ); - Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( aBathEnt ); - Handle(HYDROData_PolylineXY) aPolyline = Handle(HYDROData_PolylineXY)::DownCast( aPolyEnt ); - - if( aProfile.IsNull() || ( aPolyline.IsNull() && aBath.IsNull() ) ) - return false; + Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( + HYDROGUI_Tool::FindObjectByName( module(), aProfileName, KIND_PROFILE ) ); + Handle(HYDROData_PolylineXY) aPolyline = Handle(HYDROData_PolylineXY)::DownCast( + HYDROGUI_Tool::FindObjectByName( module(), aPolyName, KIND_POLYLINEXY ) ); + Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( + HYDROGUI_Tool::FindObjectByName( module(), aBathName, KIND_BATHYMETRY ) ); - Handle(HYDROData_ProfileUZ) aProfileUZ = aProfile->GetProfileUZ(); - if( aProfileUZ.IsNull() ) + if ( aPolyline.IsNull() || ( aProfile.IsNull() && aBath.IsNull() ) ) return false; Handle(HYDROData_Polyline3D) aResult; @@ -152,6 +147,7 @@ bool HYDROGUI_Poly3DOp::processApply( int& theUpdateFlags, aResult = myEditedObject; aResult->RemoveProfileUZ(); aResult->RemovePolylineXY(); + aResult->RemoveBathymetry(); } else { @@ -162,9 +158,21 @@ bool HYDROGUI_Poly3DOp::processApply( int& theUpdateFlags, return false; aResult->SetName( aResultName ); - aResult->SetProfileUZ( aProfileUZ ); + + if ( !aProfile.IsNull() ) + { + Handle(HYDROData_ProfileUZ) aProfileUZ = aProfile->GetProfileUZ(); + if( aProfileUZ.IsNull() ) + return false; + + aResult->SetProfileUZ( aProfileUZ ); + } + else + { + aResult->SetBathymetry( aBath ); + } + aResult->SetPolylineXY( aPolyline ); - //TODO: set bathymetry if( !myIsEdit ) { -- 2.39.2