From 81a3afc2fa400c75661571a9402416dfb839ff6c Mon Sep 17 00:00:00 2001 From: asl Date: Fri, 23 Oct 2015 09:03:29 +0300 Subject: [PATCH] automatic test on custom polylines and interpolation of imported shapes --- src/HYDROData/HYDROData_PolylineXY.cxx | 69 ++++++++++++------- src/HYDROData/HYDROData_PolylineXY.h | 9 ++- src/HYDROData/HYDROData_Tool.cxx | 14 ++++ src/HYDROData/HYDROData_Tool.h | 2 + src/HYDRO_tests/TestShape.cxx | 8 +++ src/HYDRO_tests/TestShape.h | 2 + src/HYDRO_tests/test_HYDROData_PolylineXY.cxx | 59 ++++++++++++++++ src/HYDRO_tests/test_HYDROData_PolylineXY.h | 2 + 8 files changed, 139 insertions(+), 26 deletions(-) diff --git a/src/HYDROData/HYDROData_PolylineXY.cxx b/src/HYDROData/HYDROData_PolylineXY.cxx index d47f2cb8..559947e6 100755 --- a/src/HYDROData/HYDROData_PolylineXY.cxx +++ b/src/HYDROData/HYDROData_PolylineXY.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #ifndef LIGHT_MODE #include @@ -40,6 +41,7 @@ #include #include +#include #include @@ -56,6 +58,7 @@ #include #include +#include #include #include @@ -118,7 +121,8 @@ IMPLEMENT_STANDARD_HANDLE(HYDROData_PolylineXY, HYDROData_IPolyline) IMPLEMENT_STANDARD_RTTIEXT(HYDROData_PolylineXY, HYDROData_IPolyline) HYDROData_PolylineXY::HYDROData_PolylineXY() -: HYDROData_IPolyline() +: HYDROData_IPolyline(), + myIsInCustomFlag( false ) { } @@ -253,7 +257,9 @@ bool convertEdgeToSection( const TopoDS_Edge& NCollection_Sequence& theSectTypes, NCollection_Sequence& theSectClosures, NCollection_Sequence& theSectPoints, - const bool theIsCanBeClosed ) + bool IsCanBeClosed, + bool IsInterpolationAllowed, + double theDeflection ) { Standard_Real aFirst = 0.0, aLast = 0.0; Handle(Geom_Curve) anEdgeGeomCurve = BRep_Tool::Curve( theEdge, aFirst, aLast ); @@ -266,7 +272,7 @@ bool convertEdgeToSection( const TopoDS_Edge& HYDROData_PolylineXY::SectionType aSectionType = HYDROData_PolylineXY::SECTION_POLYLINE; HYDROData_PolylineXY::PointsList aPointsList; - if ( anEdgeGeomCurve->IsKind( STANDARD_TYPE(Geom_Line) ) ) + if( anEdgeGeomCurve->IsKind( STANDARD_TYPE(Geom_Line) ) ) { Handle(Geom_Line) aGeomLine = Handle(Geom_Line)::DownCast( anEdgeGeomCurve ); @@ -280,28 +286,22 @@ bool convertEdgeToSection( const TopoDS_Edge& HYDROData_PolylineXY::Point aSectLastPoint( aLastPoint.X(), aLastPoint.Y() ); aPointsList.Append( aSectLastPoint ); } - else if ( anEdgeGeomCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) ) + else if ( anEdgeGeomCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) || IsInterpolationAllowed ) { aSectionType = HYDROData_PolylineXY::SECTION_SPLINE; - Handle(Geom_BSplineCurve) aGeomSpline = - Handle(Geom_BSplineCurve)::DownCast( anEdgeGeomCurve ); + BRepAdaptor_Curve anAdaptorCurve( theEdge ); + GCPnts_QuasiUniformDeflection aDiscrete( anAdaptorCurve, theDeflection ); - int aNbKnots = aGeomSpline->NbKnots(); + int aNbPoints = aDiscrete.NbPoints(); - TColStd_Array1OfReal aSplineKnots( 1, aNbKnots ); - aGeomSpline->Knots( aSplineKnots ); + // Decrease the number of imported poles because of last one + // pole is the closing point which are the start point + if ( anIsEdgeClosed ) aNbPoints--; - // Decrease the number of imported knots because of last one - // knot is the closing point which are the start point - if ( anIsEdgeClosed ) aNbKnots--; - - for ( int i = 1; i <= aNbKnots; ++i ) + for ( int i = 1; i <= aNbPoints; ++i ) { - const Standard_Real& aKnot = aSplineKnots.Value( i ); - - gp_Pnt aPoint; - aGeomSpline->D0( aKnot, aPoint ); + const gp_Pnt& aPoint = aDiscrete.Value( i ); HYDROData_PolylineXY::Point aSectPoint( aPoint.X(), aPoint.Y() ); aPointsList.Append( aSectPoint ); @@ -324,7 +324,9 @@ bool convertEdgeToSection( const TopoDS_Edge& return true; } -bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape ) +bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape, + bool IsInterpolationAllowed, + double theDeviation ) { if ( theShape.IsNull() ) return false; @@ -341,7 +343,8 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape ) if ( theShape.ShapeType() == TopAbs_EDGE ) { TopoDS_Edge anEdge = TopoDS::Edge( theShape ); - anIsCanBeImported = convertEdgeToSection( anEdge, aSectNames, aSectTypes, aSectClosures, aSectPoints, true ); + anIsCanBeImported = convertEdgeToSection( anEdge, aSectNames, aSectTypes, + aSectClosures, aSectPoints, true, IsInterpolationAllowed, theDeviation ); } else if ( theShape.ShapeType() == TopAbs_WIRE ) { @@ -352,7 +355,8 @@ bool HYDROData_PolylineXY::ImportShape( const TopoDS_Shape& theShape ) for ( int i = 1, n = anEdges.Length(); i <= n && anIsCanBeImported; ++i ) { TopoDS_Edge aWireEdge = TopoDS::Edge( anEdges.Value( i ) ); - anIsCanBeImported = convertEdgeToSection( aWireEdge, aSectNames, aSectTypes, aSectClosures, aSectPoints, false ); + anIsCanBeImported = convertEdgeToSection( aWireEdge, aSectNames, aSectTypes, + aSectClosures, aSectPoints, false, IsInterpolationAllowed, theDeviation ); } } @@ -835,6 +839,11 @@ void HYDROData_PolylineXY::GetSections( NCollection_Sequence( this )->Interpolate(); + } + Handle(TDataStd_ExtStringList) aNamesList; Handle(TDataStd_IntegerList) aTypesList; Handle(TDataStd_BooleanList) aClosuresList; @@ -1075,7 +1084,7 @@ HYDROData_PolylineXY::PointsList HYDROData_PolylineXY::GetPoints( const int theS if( IsCustom() ) { - //TODO: make interpolation to fill the list + const_cast( this )->Interpolate(); } Handle(TDataStd_RealList) aListX, aListY; @@ -1177,12 +1186,22 @@ void HYDROData_PolylineXY::Transform( const QTransform& theTrsf ) bool HYDROData_PolylineXY::IsCustom() const { + if( myIsInCustomFlag ) + return false; + bool isNull = GetShape().IsNull(); int aNbPoints = 0; - //TODO: to check if there is no points - //for( int i=0, n=NbSections(); i( this ); + aThat->myIsInCustomFlag = true; + for( int i=0, n=NbSections(); imyIsInCustomFlag = false; return !isNull && aNbPoints == 0; } + +void HYDROData_PolylineXY::Interpolate() +{ + ImportShape( GetShape(), true ); +} diff --git a/src/HYDROData/HYDROData_PolylineXY.h b/src/HYDROData/HYDROData_PolylineXY.h index 57ff8cad..611a2a30 100644 --- a/src/HYDROData/HYDROData_PolylineXY.h +++ b/src/HYDROData/HYDROData_PolylineXY.h @@ -127,7 +127,9 @@ public: /** * Returns the 3D presentation of all points. */ - HYDRODATA_EXPORT virtual bool ImportShape( const TopoDS_Shape& theShape ); + HYDRODATA_EXPORT virtual bool ImportShape( const TopoDS_Shape& theShape, + bool IsInterpolationAllowed = false, + double theDeviation = 1E-3 ); /** * Returns flag indicating that polyline can be edited or not. @@ -297,6 +299,8 @@ protected: */ HYDRODATA_EXPORT virtual void setEditable( const bool theIsEditable ); + HYDRODATA_EXPORT void Interpolate(); + protected: friend class HYDROData_Profile; @@ -312,6 +316,9 @@ protected: * Destructs properties of the object and object itself, removes it from the document. */ HYDRODATA_EXPORT ~HYDROData_PolylineXY(); + +private: + bool myIsInCustomFlag; }; #endif diff --git a/src/HYDROData/HYDROData_Tool.cxx b/src/HYDROData/HYDROData_Tool.cxx index 051fdc91..f6f0f5a8 100644 --- a/src/HYDROData/HYDROData_Tool.cxx +++ b/src/HYDROData/HYDROData_Tool.cxx @@ -314,3 +314,17 @@ std::ostream& operator<<( std::ostream& theStream, const TopoDS_Face& theFace ) return theStream; } +std::ostream& operator<<( std::ostream& theStream, const gp_XY& theXY ) +{ + theStream << "(" << theXY.X() << "; " << theXY.Y() << ")"; + return theStream; +} + +bool operator == ( const gp_XY& thePoint1, const gp_XY& thePoint2 ) +{ + const double EPS = 1E-3; + return + fabs( thePoint1.X() - thePoint2.X() ) < EPS && + fabs( thePoint1.Y() - thePoint2.Y() ) < EPS; + +} diff --git a/src/HYDROData/HYDROData_Tool.h b/src/HYDROData/HYDROData_Tool.h index 0eeb6487..b9b6d6d7 100644 --- a/src/HYDROData/HYDROData_Tool.h +++ b/src/HYDROData/HYDROData_Tool.h @@ -143,6 +143,8 @@ HYDRODATA_EXPORT std::ostream& operator<<( std::ostream& theStream, const QStrin HYDRODATA_EXPORT std::ostream& operator<<( std::ostream& theStream, const QColor& theText ); HYDRODATA_EXPORT std::ostream& operator<<( std::ostream& theStream, const TopoDS_Shape& theShape ); HYDRODATA_EXPORT std::ostream& operator<<( std::ostream& theStream, const TopoDS_Face& theFace ); +HYDRODATA_EXPORT bool operator == ( const gp_XY& thePoint1, const gp_XY& thePoint2 ); +HYDRODATA_EXPORT std::ostream& operator<<( std::ostream& theStream, const gp_XY& theXY ); #endif diff --git a/src/HYDRO_tests/TestShape.cxx b/src/HYDRO_tests/TestShape.cxx index 106ee9b5..1054ead9 100644 --- a/src/HYDRO_tests/TestShape.cxx +++ b/src/HYDRO_tests/TestShape.cxx @@ -8,6 +8,7 @@ #include #include #include +#include TopoDS_Edge Edge( const QList& theXYList, bool isClosed ) { @@ -41,3 +42,10 @@ TopoDS_Face Face( const QList& theXYList ) { return BRepBuilderAPI_MakeFace( Wire( theXYList, true ), Standard_True ).Face(); } + +TopoDS_Wire WireCirc( const gp_Pnt& theCenter, double theRadius ) +{ + gp_Circ aCircle( gp_Ax2( theCenter, gp_Dir( 0, 0, 1 ) ), theRadius ); + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aCircle ).Edge(); + return BRepBuilderAPI_MakeWire( anEdge ).Wire(); +} diff --git a/src/HYDRO_tests/TestShape.h b/src/HYDRO_tests/TestShape.h index d5bb2220..17acf618 100644 --- a/src/HYDRO_tests/TestShape.h +++ b/src/HYDRO_tests/TestShape.h @@ -6,8 +6,10 @@ class TopoDS_Edge; class TopoDS_Wire; class TopoDS_Face; +class gp_Pnt; TopoDS_Edge Edge( const QList& theXYList, bool isClosed = false ); TopoDS_Wire Wire( const QList& theXYList, bool isClosed = false ); +TopoDS_Wire WireCirc( const gp_Pnt& theCenter, double theRadius ); TopoDS_Face Face( const QList& theXYList ); diff --git a/src/HYDRO_tests/test_HYDROData_PolylineXY.cxx b/src/HYDRO_tests/test_HYDROData_PolylineXY.cxx index addeb5e9..c44a9f5b 100644 --- a/src/HYDRO_tests/test_HYDROData_PolylineXY.cxx +++ b/src/HYDRO_tests/test_HYDROData_PolylineXY.cxx @@ -43,6 +43,7 @@ #include #include #include +#include void test_HYDROData_PolylineXY::testPolyline() { @@ -310,4 +311,62 @@ void test_HYDROData_PolylineXY::testSplit_refs_627() anIt2.Next(); CPPUNIT_ASSERT_EQUAL( false, anIt2.More() ); anIt2.Next(); + + aDoc->Close(); +} + +void test_HYDROData_PolylineXY::test_custom_polylines() +{ + Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( 1 ); + + Handle(HYDROData_PolylineXY) aPolyline1 = + Handle(HYDROData_PolylineXY)::DownCast( aDoc->CreateObject( KIND_POLYLINEXY ) ); + Handle(HYDROData_PolylineXY) aPolyline2 = + Handle(HYDROData_PolylineXY)::DownCast( aDoc->CreateObject( KIND_POLYLINEXY ) ); + Handle(HYDROData_PolylineXY) aPolyline3 = + Handle(HYDROData_PolylineXY)::DownCast( aDoc->CreateObject( KIND_POLYLINEXY ) ); + + aPolyline1->SetName( "test1" ); + aPolyline2->SetName( "test2" ); + aPolyline3->SetName( "test3" ); + + CPPUNIT_ASSERT_EQUAL( false, aPolyline1->IsCustom() ); + aPolyline1->AddSection( "", HYDROData_IPolyline::SECTION_SPLINE, false ); + aPolyline1->Update(); + CPPUNIT_ASSERT_EQUAL( false, aPolyline1->IsCustom() ); + aPolyline1->AddPoint( 0, gp_XY( 0, 0 ) ); + aPolyline1->Update(); + CPPUNIT_ASSERT_EQUAL( false, aPolyline1->IsCustom() ); + + CPPUNIT_ASSERT_EQUAL( false, aPolyline2->IsCustom() ); + aPolyline2->SetShape( Wire( QList() << 0 << 0 << 1 << 1 << 2 << 0 ) ); + CPPUNIT_ASSERT_EQUAL( true, aPolyline2->IsCustom() ); + HYDROData_PolylineXY::PointsList aPointsList = aPolyline2->GetPoints( 0 ); + + CPPUNIT_ASSERT_EQUAL( false, aPolyline2->IsCustom() ); + CPPUNIT_ASSERT_EQUAL( 33, aPointsList.Size() ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 0, 0 ), aPointsList.Value( 1 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 0.5625, 0.808594 ), aPointsList.Value( 10 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 1.1875, 0.964844 ), aPointsList.Value( 20 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 2, 0 ), aPointsList.Value( 33 ) ); + + + CPPUNIT_ASSERT_EQUAL( false, aPolyline3->IsCustom() ); + aPolyline3->SetShape( WireCirc( gp_Pnt(), 1.0 ) ); + CPPUNIT_ASSERT_EQUAL( true, aPolyline3->IsCustom() ); + aPointsList = aPolyline3->GetPoints( 0 ); + + CPPUNIT_ASSERT_EQUAL( HYDROData_PolylineXY::SECTION_SPLINE, aPolyline3->GetSectionType( 0 ) ); + CPPUNIT_ASSERT_EQUAL( true, aPolyline3->IsClosedSection( 0 ) ); + CPPUNIT_ASSERT_EQUAL( 71, aPointsList.Size() ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 1, 0 ), aPointsList.Value( 1 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 0.699242, 0.714885 ), aPointsList.Value( 10 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( -0.110394, 0.993888 ), aPointsList.Value( 20 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( -0.839072, 0.54402 ), aPointsList.Value( 30 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( -0.952415, -0.304806 ), aPointsList.Value( 40 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( -0.367302, -0.930102 ), aPointsList.Value( 50 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 0.487173, -0.873306 ), aPointsList.Value( 60 ) ); + CPPUNIT_ASSERT_EQUAL( gp_XY( 0.996087, -0.0883801 ), aPointsList.Value( 71 ) ); + + aDoc->Close(); } diff --git a/src/HYDRO_tests/test_HYDROData_PolylineXY.h b/src/HYDRO_tests/test_HYDROData_PolylineXY.h index 88094b58..3a7b53bb 100644 --- a/src/HYDRO_tests/test_HYDROData_PolylineXY.h +++ b/src/HYDRO_tests/test_HYDROData_PolylineXY.h @@ -27,6 +27,7 @@ class test_HYDROData_PolylineXY : public CppUnit::TestFixture { CPPUNIT_TEST( test_presentation ); CPPUNIT_TEST( test_extraction_immersible_zone ); CPPUNIT_TEST( test_extraction_channel_refs_611 ); + CPPUNIT_TEST( test_custom_polylines ); CPPUNIT_TEST_SUITE_END(); private: @@ -49,6 +50,7 @@ public: void test_extraction_immersible_zone(); void test_extraction_channel_refs_611(); void test_presentation(); + void test_custom_polylines(); }; CPPUNIT_TEST_SUITE_REGISTRATION(test_HYDROData_PolylineXY); -- 2.39.2