From 22e3cfcf831f66ef645eeab59bb2f1e575452032 Mon Sep 17 00:00:00 2001 From: asl Date: Wed, 14 Oct 2015 11:28:35 +0300 Subject: [PATCH] #650: land cover addition test --- src/HYDROData/HYDROData_LandCoverMap.cxx | 77 +++++++++++++------ src/HYDROData/HYDROData_LandCoverMap.h | 5 +- src/HYDRO_tests/TestViewer.cxx | 38 +++++++-- src/HYDRO_tests/TestViewer.h | 6 +- .../test_HYDROData_LandCoverMap.cxx | 49 +++++++----- 5 files changed, 123 insertions(+), 52 deletions(-) diff --git a/src/HYDROData/HYDROData_LandCoverMap.cxx b/src/HYDROData/HYDROData_LandCoverMap.cxx index c801780f..887fc9bd 100644 --- a/src/HYDROData/HYDROData_LandCoverMap.cxx +++ b/src/HYDROData/HYDROData_LandCoverMap.cxx @@ -31,13 +31,14 @@ #include #include #include +#include #include IMPLEMENT_STANDARD_HANDLE(HYDROData_LandCoverMap, HYDROData_Entity) IMPLEMENT_STANDARD_RTTIEXT(HYDROData_LandCoverMap, HYDROData_Entity) -class HYDROData_MapOfShapeToStricklerType : public NCollection_IndexedDataMap +class HYDROData_MapOfFaceToStricklerType : public NCollection_IndexedDataMap { }; @@ -56,7 +57,11 @@ HYDROData_LandCoverMap::Iterator::Iterator( const HYDROData_LandCoverMap& theMap */ void HYDROData_LandCoverMap::Iterator::Init( const HYDROData_LandCoverMap& theMap ) { - myIterator = new TopoDS_Iterator( theMap.GetShape() ); + TopoDS_Shape aShape = theMap.GetShape(); + if( aShape.IsNull() ) + myIterator = 0; + else + myIterator = new TopoDS_Iterator( aShape ); myIndex = 0; theMap.myLab.FindChild( DataTag_Types ).FindAttribute( TDataStd_ExtStringArray::GetID(), myArray ); } @@ -75,7 +80,7 @@ HYDROData_LandCoverMap::Iterator::~Iterator() */ bool HYDROData_LandCoverMap::Iterator::More() const { - return !myArray.IsNull() && myIterator->More(); + return !myArray.IsNull() && myIterator && myIterator->More(); } /** @@ -83,7 +88,8 @@ bool HYDROData_LandCoverMap::Iterator::More() const */ void HYDROData_LandCoverMap::Iterator::Next() { - myIterator->Next(); + if( myIterator ) + myIterator->Next(); } /** @@ -92,7 +98,10 @@ void HYDROData_LandCoverMap::Iterator::Next() */ TopoDS_Face HYDROData_LandCoverMap::Iterator::Face() const { - return TopoDS::Face( myIterator->Value() ); + if( myIterator ) + return TopoDS::Face( myIterator->Value() ); + else + return TopoDS_Face(); } /** @@ -254,8 +263,12 @@ void HYDROData_LandCoverMap::SetShape( const TopoDS_Shape& theShape ) */ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, const QString& theNewType ) { + if( theNewShape.IsNull() ) + return false; + BOPCol_ListOfShape aShapesList; BOPAlgo_PaveFiller aPaveFiller; + HYDROData_MapOfFaceToStricklerType aNewFaces; // add faces to shapes list Iterator anIt( *this ); @@ -263,6 +276,13 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co aShapesList.Append( anIt.Face() ); aShapesList.Append( theNewShape ); + if( aShapesList.Size()==1 && theNewShape.ShapeType()==TopAbs_FACE ) + { + aNewFaces.Add( TopoDS::Face( theNewShape ), theNewType ); + StoreLandCovers( aNewFaces ); + return true; + } + // prepare pave filler aPaveFiller.SetArguments( aShapesList ); aPaveFiller.Perform(); @@ -284,32 +304,39 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co return false; // analysis of the history - BOPCol_DataMapOfShapeListOfShape aSplits = aBuilder.Splits(); + // a. to fill map of shapes which come from the new face + NCollection_IndexedMap aShapesFromNewFace; + //std::cout << "new: " << theNewShape << " " << theNewType << std::endl; + TopTools_ListOfShape aModified = aBuilder.Modified( theNewShape ); + TopTools_ListIteratorOfListOfShape aMIt( aModified ); + for( ; aMIt.More(); aMIt.Next() ) + { + //std::cout << " " << aMIt.Value() << std::endl; + aShapesFromNewFace.Add( aMIt.Value() ); + } - // a. fill map of shape => type for initial faces - HYDROData_MapOfShapeToStricklerType anOldFaces; + // b. to fill map of parts except parts from new face anIt.Init( *this ); for( ; anIt.More(); anIt.Next() ) - anOldFaces.Add( anIt.Face(), anIt.StricklerType() ); - - // b. fill map of shape => type for split faces without the new face - HYDROData_MapOfShapeToStricklerType aNewFaces; - BOPCol_DataMapOfShapeListOfShape::Iterator aSplitIt( aSplits ); - for( ; aSplitIt.More(); aSplitIt.Next() ) { - TopoDS_Shape anInitial = aSplitIt.Key(); - if( anInitial==theNewShape ) - continue; - QString aType = anOldFaces.FindFromKey( anInitial ); - BOPCol_ListOfShape aSplitFaces = aSplitIt.Value(); - BOPCol_ListOfShape::Iterator aSFIt( aSplitFaces ); - for( ; aSFIt.More(); aSFIt.Next() ) - aNewFaces.Add( aSFIt.Value(), aType ); + QString aSType = anIt.StricklerType(); + //std::cout << anIt.Face() << " " << anIt.StricklerType() << std::endl; + TopTools_ListOfShape aModified = aBuilder.Modified( anIt.Face() ); + TopTools_ListIteratorOfListOfShape aMIt( aModified ); + for( ; aMIt.More(); aMIt.Next() ) + { + TopoDS_Shape aShape = aMIt.Value(); + bool isFace = aShape.ShapeType()==TopAbs_FACE; + bool isAlsoFromNew = aShapesFromNewFace.Contains( aShape ); + //std::cout << " " << aShape << " " << isAlsoFromNew << std::endl; + if( isFace && !isAlsoFromNew ) + aNewFaces.Add( TopoDS::Face( aShape ), aSType ); + } } // c. add the new shape if it is face with its type if( theNewShape.ShapeType()==TopAbs_FACE ) - aNewFaces.Add( theNewShape, theNewType ); + aNewFaces.Add( TopoDS::Face( theNewShape ), theNewType ); // convert map of shape to type to compound and list of types StoreLandCovers( aNewFaces ); @@ -320,7 +347,7 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co Replace the set of land covers in the land cover map @param theMap the map of shape (face) to Strickler type (string) */ -void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfShapeToStricklerType& theMap ) +void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfFaceToStricklerType& theMap ) { TopoDS_Compound aCompound; BRep_Builder aCompoundBuilder; @@ -329,7 +356,7 @@ void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfShapeToStrick int n = theMap.Size(); Handle( TDataStd_ExtStringArray ) aTypes = TDataStd_ExtStringArray::Set( myLab.FindChild( DataTag_Types ), 0, n-1, Standard_True ); - HYDROData_MapOfShapeToStricklerType::Iterator aNFIt( theMap ); + HYDROData_MapOfFaceToStricklerType::Iterator aNFIt( theMap ); for( int i=0; aNFIt.More(); aNFIt.Next(), i++ ) { aCompoundBuilder.Add( aCompound, aNFIt.Key() ); diff --git a/src/HYDROData/HYDROData_LandCoverMap.h b/src/HYDROData/HYDROData_LandCoverMap.h index bcc4c0c9..e09d5e8b 100644 --- a/src/HYDROData/HYDROData_LandCoverMap.h +++ b/src/HYDROData/HYDROData_LandCoverMap.h @@ -30,7 +30,7 @@ class TopoDS_Iterator; class TopTools_ListOfShape; class Handle( HYDROData_Polyline ); class Handle( HYDROData_Object ); -class HYDROData_MapOfShapeToStricklerType; +class HYDROData_MapOfFaceToStricklerType; class HYDROData_LandCoverMap : public HYDROData_Entity { @@ -86,13 +86,14 @@ protected: void SetShape( const TopoDS_Shape& ); bool LocalPartition( const TopoDS_Shape&, const QString& theNewType ); - void StoreLandCovers( const HYDROData_MapOfShapeToStricklerType& ); + void StoreLandCovers( const HYDROData_MapOfFaceToStricklerType& ); public: DEFINE_STANDARD_RTTI( HYDROData_LandCoverMap ); private: friend class Iterator; + friend class test_HYDROData_LandCoverMap; }; #endif diff --git a/src/HYDRO_tests/TestViewer.cxx b/src/HYDRO_tests/TestViewer.cxx index 4fc29d34..e0a532c4 100644 --- a/src/HYDRO_tests/TestViewer.cxx +++ b/src/HYDRO_tests/TestViewer.cxx @@ -5,6 +5,7 @@ #include #include #include +#include #include OCCViewer_ViewManager* TestViewer::myViewManager = 0; @@ -44,19 +45,46 @@ Handle(AIS_InteractiveContext) context() return TestViewer::viewer()->getAISContext(); } -void TestViewer::show( const TopoDS_Shape& theShape, bool isFitAll ) +void TestViewer::show( const TopoDS_Shape& theShape, const QColor& theColor, int theMode ) { - context()->EraseAll(); + QColor aColor = theColor; + if( !aColor.isValid() ) + { + // random color + int aHue = rand()%255; + aColor = QColor::fromHsl( aHue, 255, 128 ); + } + + double r = aColor.red() / 255.0; + double g = aColor.green() / 255.0; + double b = aColor.blue() / 255.0; + Handle(AIS_Shape) aShape = new AIS_Shape( theShape ); - context()->Display( aShape, AIS_Shaded, 0, Standard_False ); + aShape->SetMaterial( Graphic3d_NOM_PLASTIC ); + aShape->SetColor( Quantity_Color( r, g, b, Quantity_TOC_RGB ) ); + context()->Display( aShape, theMode, 0, Standard_False ); +} + +void TestViewer::show( const TopoDS_Shape& theShape, int theMode, bool isFitAll ) +{ + context()->EraseAll(); + + if( theShape.ShapeType()==TopAbs_COMPOUND ) + { + TopoDS_Iterator anIt( theShape ); + for( ; anIt.More(); anIt.Next() ) + show( anIt.Value(), QColor(), theMode ); + } + else + show( theShape, QColor(), theMode ); viewWindow()->onTopView(); viewWindow()->onFitAll(); } -void TestViewer::dump( const TopoDS_Shape& theShape, const QString& theName ) +void TestViewer::dump( const TopoDS_Shape& theShape, int theMode, const QString& theName ) { - show( theShape ); + show( theShape, theMode, true ); QImage anImage = viewWindow()->dumpView(); QString aPath = QDir::tempPath() + "/" + theName + ".png"; diff --git a/src/HYDRO_tests/TestViewer.h b/src/HYDRO_tests/TestViewer.h index f184b5da..8b843ad1 100644 --- a/src/HYDRO_tests/TestViewer.h +++ b/src/HYDRO_tests/TestViewer.h @@ -6,6 +6,7 @@ class OCCViewer_Viewer; class OCCViewer_ViewWindow; class TopoDS_Shape; class QString; +class QColor; class TestViewer { @@ -14,8 +15,9 @@ public: static OCCViewer_Viewer* viewer(); static OCCViewer_ViewWindow* viewWindow(); - static void show( const TopoDS_Shape& theShape, bool isFitAll = true ); - static void dump( const TopoDS_Shape& theShape, const QString& theName ); + static void show( const TopoDS_Shape& theShape, const QColor& theColor, int theMode ); + static void show( const TopoDS_Shape& theShape, int theMode, bool isFitAll = true ); + static void dump( const TopoDS_Shape& theShape, int theMode, const QString& theName ); private: static OCCViewer_ViewManager* myViewManager; diff --git a/src/HYDRO_tests/test_HYDROData_LandCoverMap.cxx b/src/HYDRO_tests/test_HYDROData_LandCoverMap.cxx index d81d898c..d2df73aa 100644 --- a/src/HYDRO_tests/test_HYDROData_LandCoverMap.cxx +++ b/src/HYDRO_tests/test_HYDROData_LandCoverMap.cxx @@ -20,32 +20,28 @@ #include #include #include +#include +#include #include #include #include -#include +#include +#include +#include +#include +#include -TopoDS_Edge Spline( bool isClosed, double x, double y, ... ) +TopoDS_Edge Spline( const QList& theXYList, bool isClosed = false ) { - va_list anArgs; - va_start( anArgs, y ); - QList aPointsList; - while( true ) + int n = theXYList.size()/2; + Handle(TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt( 1, n ); + for( int i=1; i<=n; i++ ) { - double x = va_arg( anArgs, double ); - if( x <= 0 ) - break; - double y = va_arg( anArgs, double ); + double x = theXYList[2*i-2]; + double y = theXYList[2*i-1]; gp_Pnt aPnt( x, y, 0 ); - aPointsList.append( aPnt ); + aPointsArray->SetValue( i, aPnt ); } - va_end( anArgs ); - - int n = aPointsList.size(); - Handle(TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt( 1, n ); - for( int i=1; i<=n; i++ ) - aPointsArray->SetValue( i, aPointsList[i-1] ); - GeomAPI_Interpolate anInterpolator( aPointsArray, isClosed, 1E-3 ); anInterpolator.Perform(); bool aResult = anInterpolator.IsDone() == Standard_True; @@ -58,6 +54,17 @@ TopoDS_Edge Spline( bool isClosed, double x, double y, ... ) return TopoDS_Edge(); } +TopoDS_Face LandCover( const QList& theXYList ) +{ + TopoDS_Edge anEdge = Spline( theXYList, true ); + if( anEdge.IsNull() ) + return TopoDS_Face(); + + TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire(); + TopoDS_Face aFace = BRepBuilderAPI_MakeFace( aWire, Standard_True ).Face(); + return aFace; +} + void test_HYDROData_LandCoverMap::test_local_partition() { Handle(HYDROData_Document) aDoc = HYDROData_Document::Document(1); @@ -67,7 +74,13 @@ void test_HYDROData_LandCoverMap::test_local_partition() CPPUNIT_ASSERT_EQUAL( KIND_LAND_COVER_MAP, aMap->GetKind() ); + TopoDS_Face aLC1 = LandCover( QList() << 10 << 10 << 50 << 20 << 30 << 50 << 15 << 30 ); + CPPUNIT_ASSERT_EQUAL( true, aMap->LocalPartition( aLC1, "test1" ) ); + + TopoDS_Face aLC2 = LandCover( QList() << 30 << 20 << 60 << 10 << 70 << 35 << 40 << 40 ); + CPPUNIT_ASSERT_EQUAL( true, aMap->LocalPartition( aLC2, "test2" ) ); + TestViewer::show( aMap->GetShape(), AIS_Shaded, true ); aDoc->Close(); } -- 2.39.2