From d1fb3cba49689a5773aaab41d638513026757fae Mon Sep 17 00:00:00 2001 From: adv Date: Thu, 28 Nov 2013 06:18:14 +0000 Subject: [PATCH] Stream object implementation. --- src/HYDROData/HYDROData_Object.cxx | 36 ++++- src/HYDROData/HYDROData_Object.h | 10 ++ src/HYDROData/HYDROData_Stream.cxx | 218 ++++++++++++++++++++++++++++- src/HYDROData/HYDROData_Stream.h | 71 ++++++++++ 4 files changed, 326 insertions(+), 9 deletions(-) diff --git a/src/HYDROData/HYDROData_Object.cxx b/src/HYDROData/HYDROData_Object.cxx index 4bc6d235..45ea5f01 100644 --- a/src/HYDROData/HYDROData_Object.cxx +++ b/src/HYDROData/HYDROData_Object.cxx @@ -52,20 +52,44 @@ void HYDROData_Object::RemoveBathymetry() TopoDS_Shape HYDROData_Object::getTopShape() const { - Handle(TNaming_NamedShape) aNamedShape; - if( myLab.FindChild( DataTag_TopShape ).FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) ) - return aNamedShape->Get(); + TDF_Label aLabel = myLab.FindChild( DataTag_TopShape, false ); + if ( !aLabel.IsNull() ) + { + Handle(TNaming_NamedShape) aNamedShape; + if( aLabel.FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) ) + return aNamedShape->Get(); + } + return TopoDS_Shape(); } +void HYDROData_Object::removeTopShape() +{ + TDF_Label aLabel = myLab.FindChild( DataTag_TopShape, false ); + if ( !aLabel.IsNull() ) + aLabel.ForgetAllAttributes(); +} + TopoDS_Shape HYDROData_Object::getShape3D() const { - Handle(TNaming_NamedShape) aNamedShape; - if( myLab.FindChild( DataTag_Shape3D ).FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) ) - return aNamedShape->Get(); + TDF_Label aLabel = myLab.FindChild( DataTag_Shape3D, false ); + if ( !aLabel.IsNull() ) + { + Handle(TNaming_NamedShape) aNamedShape; + if( aLabel.FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) ) + return aNamedShape->Get(); + } + return TopoDS_Shape(); } +void HYDROData_Object::removeShape3D() +{ + TDF_Label aLabel = myLab.FindChild( DataTag_Shape3D, false ); + if ( !aLabel.IsNull() ) + aLabel.ForgetAllAttributes(); +} + void HYDROData_Object::SetFillingColor( const QColor& theColor ) { return SetColor( theColor, DataTag_FillingColor ); diff --git a/src/HYDROData/HYDROData_Object.h b/src/HYDROData/HYDROData_Object.h index 594bbd60..eda73755 100644 --- a/src/HYDROData/HYDROData_Object.h +++ b/src/HYDROData/HYDROData_Object.h @@ -119,11 +119,21 @@ protected: */ HYDRODATA_EXPORT TopoDS_Shape getTopShape() const; + /** + * Removes the top shape from data label of the object. + */ + HYDRODATA_EXPORT void removeTopShape(); + + /** * Retrieve the 3d shape of the object from data label. */ HYDRODATA_EXPORT TopoDS_Shape getShape3D() const; + /** + * Removes the 3d shape from data label of the object. + */ + HYDRODATA_EXPORT void removeShape3D(); }; #endif diff --git a/src/HYDROData/HYDROData_Stream.cxx b/src/HYDROData/HYDROData_Stream.cxx index 111eb9b0..2b5d29ea 100644 --- a/src/HYDROData/HYDROData_Stream.cxx +++ b/src/HYDROData/HYDROData_Stream.cxx @@ -2,8 +2,18 @@ #include "HYDROData_Stream.h" #include "HYDROData_Document.h" +#include "HYDROData_PolylineXY.h" +#include "HYDROData_Profile.h" -#include +#include +#include +#include +#include + +#include +#include +#include +#include #include @@ -46,15 +56,217 @@ QStringList HYDROData_Stream::DumpToPython( MapOfTreatedObjects& theTreatedObjec TopoDS_Shape HYDROData_Stream::GetTopShape() const { - // TODO return getTopShape(); } TopoDS_Shape HYDROData_Stream::GetShape3D() const { - // TODO return getShape3D(); } +void HYDROData_Stream::Update() +{ + removeTopShape(); + removeShape3D(); + + Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); + HYDROData_SequenceOfObjects aRefProfiles = GetProfiles(); + if ( aHydAxis.IsNull() || aRefProfiles.IsEmpty() ) + return; + + TopoDS_Shell a2dShell; + BRep_Builder a2dShellBuilder; + a2dShellBuilder.MakeShell( a2dShell ); + + bool anIsFirst = true; + gp_Pnt aPrevFirstPoint, aPrevLastPoint; + + // Construct the top presentation + HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles ); + for ( ; anIter.More(); anIter.Next() ) + { + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( anIter.Value() ); + if ( aProfile.IsNull() ) + continue; + + gp_XY aPnt1, aPnt2; + if ( !aProfile->GetFirstPoint( aPnt1 ) || !aProfile->GetLastPoint( aPnt2 ) ) + continue; + + gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 ); + gp_Pnt aCurLastPoint( aPnt2.X(), aPnt2.Y(), 0 ); + + if ( anIsFirst ) + { + aPrevFirstPoint = aCurFirstPoint; + aPrevLastPoint = aCurLastPoint; + anIsFirst = false; + continue; + } + + BRepBuilderAPI_MakeEdge aFirstEdge( aPrevFirstPoint, aPrevLastPoint ); + BRepBuilderAPI_MakeEdge aSecondEdge( aPrevLastPoint, aCurLastPoint ); + BRepBuilderAPI_MakeEdge aThirdEdge( aCurLastPoint, aCurFirstPoint ); + BRepBuilderAPI_MakeEdge aFourthEdge( aCurFirstPoint, aPrevFirstPoint ); + + BRepBuilderAPI_MakeWire aMakeWire( aFirstEdge.Edge(), aSecondEdge.Edge(), + aThirdEdge.Edge(), aFourthEdge.Edge() ); + + TopoDS_Wire aSectProfileWire = aMakeWire.Wire(); + + BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True ); + aMakeFace.Build(); + if( aMakeFace.IsDone() ) + { + a2dShellBuilder.Add( a2dShell, aMakeFace.Face() ); + } + } + + SetTopShape( a2dShell ); + + // Construct the 3D presentation + /// TODO +} + +bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis ) +{ + Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis(); + if ( theAxis.IsNull() || IsEqual( aPrevAxis, theAxis ) ) + return false; + + TopoDS_Wire aHydraulicWire = TopoDS::Wire( theAxis->GetShape() ); + if ( aHydraulicWire.IsNull() ) + return false; // The polyline must be a single wire + + SetReferenceObject( theAxis, DataTag_HydraulicAxis ); + + // Update the order of profiles + updateProfilesOrder(); + + // Indicate model of the need to update the stream presentation + SetToUpdate( true ); + + return true; +} + +Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const +{ + return Handle(HYDROData_PolylineXY)::DownCast( + GetReferenceObject( DataTag_HydraulicAxis ) ); +} + +void HYDROData_Stream::RemoveHydraulicAxis() +{ + Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis(); + if ( aPrevAxis.IsNull() ) + return; + + ClearReferenceObjects( DataTag_HydraulicAxis ); + + // We remove the reference profiles + RemoveProfiles(); + + // Indicate model of the need to update the stream presentation + SetToUpdate( true ); +} + +bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile ) const +{ + Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); + if ( theProfile.IsNull() || aHydAxis.IsNull() ) + return false; + + TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); + TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() ); + if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() ) + return false; + + // TODO + return true; +} + +bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile ) +{ + if ( theProfile.IsNull() ) + return false; + + if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile ) ) + return false; // Object is already in reference list or it has no intersection + + insertProfileInToOrder( theProfile ); + + // Indicate model of the need to update the stream presentation + SetToUpdate( true ); + + return true; +} + +HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const +{ + return GetReferenceObjects( DataTag_Profile ); +} + +bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile ) +{ + if ( theProfile.IsNull() || !HasReference( theProfile, DataTag_Profile ) ) + return false; + + RemoveReferenceObject( theProfile->Label(), DataTag_Profile ); + + // Indicate model of the need to update the stream presentation + SetToUpdate( true ); + + return true; +} + +void HYDROData_Stream::RemoveProfiles() +{ + bool anIsToUpdate = IsMustBeUpdated() || NbReferenceObjects( DataTag_Profile ) > 0; + + ClearReferenceObjects( DataTag_Profile ); + + // Indicate model of the need to update the stream presentation + SetToUpdate( anIsToUpdate ); +} + +void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile ) +{ + Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); + if ( theProfile.IsNull() || aHydAxis.IsNull() ) + return; + + TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); + TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() ); + if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() ) + return; + + // TODO +} + +void HYDROData_Stream::updateProfilesOrder() +{ + HYDROData_SequenceOfObjects aRefProfiles = GetProfiles(); + if ( aRefProfiles.IsEmpty() ) + return; + + // At first we remove all profiles from order + RemoveProfiles(); + + Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); + if ( aHydAxis.IsNull() ) + return; + + HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles ); + for ( ; anIter.More(); anIter.Next() ) + { + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( anIter.Value() ); + if ( aProfile.IsNull() || !HasIntersection( aProfile ) ) + continue; + + insertProfileInToOrder( aProfile ); + } +} diff --git a/src/HYDROData/HYDROData_Stream.h b/src/HYDROData/HYDROData_Stream.h index 34d70a24..c65e3193 100644 --- a/src/HYDROData/HYDROData_Stream.h +++ b/src/HYDROData/HYDROData_Stream.h @@ -6,6 +6,9 @@ DEFINE_STANDARD_HANDLE(HYDROData_Stream, HYDROData_NaturalObject) +class Handle(HYDROData_PolylineXY); +class Handle(HYDROData_Profile); + /**\class HYDROData_Stream * \brief * @@ -19,6 +22,8 @@ protected: enum DataTag { DataTag_First = HYDROData_NaturalObject::DataTag_First + 100, ///< first tag, to reserve + DataTag_HydraulicAxis, ///< reference hydraulic axis + DataTag_Profile, ///< reference profiles }; public: @@ -44,6 +49,72 @@ public: */ HYDRODATA_EXPORT virtual TopoDS_Shape GetShape3D() const; + /** + * Update the shape presentations of stream. + * Call this method whenever you made changes for stream data. + */ + HYDRODATA_EXPORT virtual void Update(); + + +public: + // Public methods to work with Stream + + /** + * Sets reference hydraulic axis object for stream. + */ + HYDRODATA_EXPORT virtual bool SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis ); + + /** + * Returns reference hydraulic axis object of stream. + */ + HYDRODATA_EXPORT virtual Handle(HYDROData_PolylineXY) GetHydraulicAxis() const; + + /** + * Remove reference hydraulic axis object from stream. + */ + HYDRODATA_EXPORT virtual void RemoveHydraulicAxis(); + + + /** + * Returns true if profile has the intersection with reference hydraulic axis. + */ + HYDRODATA_EXPORT virtual bool HasIntersection( const Handle(HYDROData_Profile)& theProfile ) const; + + + /** + * Add new one reference profile object for stream. + */ + HYDRODATA_EXPORT virtual bool AddProfile( const Handle(HYDROData_Profile)& theProfile ); + + /** + * Returns all reference profile objects of stream. + */ + HYDRODATA_EXPORT virtual HYDROData_SequenceOfObjects GetProfiles() const; + + /** + * Removes reference profile object from stream. + */ + HYDRODATA_EXPORT virtual bool RemoveProfile( const Handle(HYDROData_Profile)& theProfile ); + + /** + * Removes all reference profile objects from stream. + */ + HYDRODATA_EXPORT virtual void RemoveProfiles(); + + +protected: + + /** + * Insert one profile in to the stream profiles order. + */ + void insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile ); + + /** + * Fully recompute the order of all profiles in accordance with reference hydraulic axis. + * If hydraulic axis is not set all profiles will be removed from order. + */ + void updateProfilesOrder(); + protected: friend class HYDROData_Iterator; -- 2.39.2