From 5ff8b7c83d889d383998207a55792c165afbf146 Mon Sep 17 00:00:00 2001 From: mzn Date: Thu, 18 Jun 2015 17:16:42 +0300 Subject: [PATCH] refs #570: Land Cover: the partition algorithm (draft) --- src/HYDROData/HYDROData_CalculationCase.cxx | 106 +++++++++---------- src/HYDROData/HYDROData_CalculationCase.h | 4 +- src/HYDROData/HYDROData_SplitToZonesTool.cxx | 30 ++++-- src/HYDROData/HYDROData_SplitToZonesTool.h | 2 + src/HYDROGUI/HYDROGUI_CalculationDlg.cxx | 21 ++-- src/HYDROGUI/HYDROGUI_DataModel.cxx | 24 +++-- src/HYDROGUI/HYDROGUI_DataModel.h | 4 +- src/HYDROGUI/resources/HYDROGUI_msg_en.ts | 4 + src/HYDROPy/HYDROData_CalculationCase.sip | 6 +- 9 files changed, 117 insertions(+), 84 deletions(-) diff --git a/src/HYDROData/HYDROData_CalculationCase.cxx b/src/HYDROData/HYDROData_CalculationCase.cxx index df5e196a..e5fda65c 100644 --- a/src/HYDROData/HYDROData_CalculationCase.cxx +++ b/src/HYDROData/HYDROData_CalculationCase.cxx @@ -266,68 +266,56 @@ void HYDROData_CalculationCase::Update() return; // Split to zones - Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline(); - HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects(); - if ( aGeomObjects.IsEmpty() ) - return; - - HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups(); - - HYDROData_SplitToZonesTool::SplitDataList aSplitObjects = - HYDROData_SplitToZonesTool::Split( aGeomObjects, aGeomGroups, aBoundaryPolyline ); - if ( aSplitObjects.isEmpty() ) - return; - HYDROData_SplitToZonesTool::SplitDataList aZonesList, anEdgesList; - HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitObjects ); - while( anIter.hasNext() ) - { - const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next(); - if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone ) - aZonesList.append( aSplitData ); - else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge ) - anEdgesList.append( aSplitData ); + Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline(); + HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects(); + if ( !aGeomObjects.IsEmpty() ) { + HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups(); + + HYDROData_SplitToZonesTool::SplitDataList aSplitObjects = + HYDROData_SplitToZonesTool::Split( aGeomObjects, aGeomGroups, aBoundaryPolyline ); + if ( !aSplitObjects.isEmpty() ) { + HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitObjects ); + while( anIter.hasNext() ) { + const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next(); + if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone ) + aZonesList.append( aSplitData ); + else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge ) + anEdgesList.append( aSplitData ); + } + } } - // TODO: Split to land cover zones - /*HYDROData_SequenceOfObjects aLandCovers = GetLandCovers(); - if ( aLandCovers.IsEmpty() ) - return; - - HYDROData_SplitToZonesTool::SplitDataList aSplitLandCoverObjects = - HYDROData_SplitToZonesTool::Split( aLandCovers, ... ); - if ( aSplitLandCoverObjects.isEmpty() ) - return; - - HYDROData_SplitToZonesTool::SplitDataList aLandCoverZonesList, aLandCoverEdgesList; - - HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitLandCoverObjects ); - while( anIter.hasNext() ) - { - const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next(); - if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone ) - aLandCoverZonesList.append( aSplitData ); - else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge ) - aLandCoverEdgesList.append( aSplitData ); - }*/ + // Split to land cover zones + HYDROData_SplitToZonesTool::SplitDataList aLandCoverZonesList; + + HYDROData_SequenceOfObjects aLandCovers = GetLandCovers(); + if ( !aLandCovers.IsEmpty() ) { + HYDROData_SplitToZonesTool::SplitDataList aSplitLandCoverObjects = + HYDROData_SplitToZonesTool::Split( aLandCovers ); + if ( !aSplitLandCoverObjects.isEmpty() ) { + HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitLandCoverObjects ); + while( anIter.hasNext() ) { + const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next(); + if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone ) + aLandCoverZonesList.append( aSplitData ); + } + } + } switch( GetAssignmentMode() ) { case MANUAL: CreateRegionsDef( aDocument, aZonesList, false ); - // TODO: Create land cover regions in manual mode - //CreateRegionsDef( aDocument, aLandCoverZonesList, true ); + CreateRegionsDef( aDocument, aLandCoverZonesList, true ); break; case AUTOMATIC: CreateRegionsAuto( aDocument, aZonesList, false ); - // TODO: Create land cover regions in automatic mode - //CreateRegionsAuto( aDocument, aLandCoverZonesList, true ); + CreateRegionsAuto( aDocument, aLandCoverZonesList, true ); break; } CreateEdgeGroupsDef( aDocument, anEdgesList ); - // TODO: Process land cover edges - //CreateEdgeGroupsDef( aDocument, aLandCoverEdgesList ); } void HYDROData_CalculationCase::CreateRegionsDef( const Handle(HYDROData_Document)& theDoc, @@ -360,10 +348,10 @@ void HYDROData_CalculationCase::CreateRegionsAuto( const Handle(HYDROData_Docume HYDROData_PriorityQueue aPr( this, DataTag_CustomRules ); // 1. First we create a default region for each object included into the calculation case - HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects(); - for( int i=aGeomObjects.Lower(), n=aGeomObjects.Upper(); i<=n; i++ ) + HYDROData_SequenceOfObjects anObjects = theLandCover ? GetLandCovers() : GetGeometryObjects(); + for( int i = anObjects.Lower(), n = anObjects.Upper(); i<=n; i++ ) { - Handle(HYDROData_Object) anObj = Handle(HYDROData_Object)::DownCast( aGeomObjects.Value( i ) ); + Handle(HYDROData_Entity) anObj = anObjects.Value( i ); if( anObj.IsNull() ) continue; QString anObjName = anObj->GetName(); @@ -656,7 +644,10 @@ bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRe if ( theRegion.IsNull() ) return false; - if ( HasReference( theRegion, DataTag_Region ) ) + HYDROData_CalculationCase::DataTag aDataTag = + theLandCover ? DataTag_LandCoverRegion : DataTag_Region; + + if ( HasReference( theRegion, aDataTag ) ) return false; // Object is already in reference list // Move the region from other calculation @@ -667,13 +658,13 @@ bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRe Handle(HYDROData_Region) aNewRegion = addNewRegion( aDocument, CALCULATION_REGIONS_PREF, theLandCover ); theRegion->CopyTo( aNewRegion ); - aFatherCalc->RemoveRegion( theRegion ); + aFatherCalc->RemoveRegion( theRegion, theLandCover ); theRegion->SetLabel( aNewRegion->Label() ); } else { - AddReferenceObject( theRegion, DataTag_Region ); + AddReferenceObject( theRegion, aDataTag ); } return true; @@ -719,12 +710,15 @@ void HYDROData_CalculationCase::UpdateRegionsOrder() } } -void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion ) +void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion, + const bool theLandCover ) { if ( theRegion.IsNull() ) return; - RemoveReferenceObject( theRegion->Label(), DataTag_Region ); + HYDROData_CalculationCase::DataTag aDataTag = + theLandCover ? DataTag_LandCoverRegion : DataTag_Region; + RemoveReferenceObject( theRegion->Label(), aDataTag ); // Remove region from data model Handle(HYDROData_CalculationCase) aFatherCalc = @@ -1037,8 +1031,6 @@ bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var theGeomEngine, // Get faces TopTools_ListOfShape aFaces; HYDROData_SequenceOfObjects aCaseRegions = GetRegions( false ); - // TODO: process land cover faces - //aCaseRegions.Append( GetRegions( true ) ); HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions ); for ( ; aRegionIter.More(); aRegionIter.Next() ) { diff --git a/src/HYDROData/HYDROData_CalculationCase.h b/src/HYDROData/HYDROData_CalculationCase.h index 6c13eacb..fa0edeb1 100644 --- a/src/HYDROData/HYDROData_CalculationCase.h +++ b/src/HYDROData/HYDROData_CalculationCase.h @@ -241,6 +241,7 @@ public: /** * Returns all reference regions of calculation case. + * \param theLandCover if true - land cover regions will be returned */ HYDRODATA_EXPORT virtual HYDROData_SequenceOfObjects GetRegions( const bool theLandCover ) const; @@ -252,7 +253,8 @@ public: /** * Removes reference region from calculation case. */ - HYDRODATA_EXPORT virtual void RemoveRegion( const Handle(HYDROData_Region)& theRegion ); + HYDRODATA_EXPORT virtual void RemoveRegion( const Handle(HYDROData_Region)& theRegion, + const bool theLandCover ); /** * Removes all reference regions from calculation case. diff --git a/src/HYDROData/HYDROData_SplitToZonesTool.cxx b/src/HYDROData/HYDROData_SplitToZonesTool.cxx index 01027235..cd7a2d0d 100644 --- a/src/HYDROData/HYDROData_SplitToZonesTool.cxx +++ b/src/HYDROData/HYDROData_SplitToZonesTool.cxx @@ -19,6 +19,7 @@ #include "HYDROData_SplitToZonesTool.h" #include "HYDROData_PolylineXY.h" +#include "HYDROData_LandCover.h" #include "HYDROData_ShapesGroup.h" #include #include @@ -139,12 +140,19 @@ HYDROData_SplitToZonesTool::SplitDataList #endif for( int anIndex = 1, aLength = theObjectList.Length(); anIndex <= aLength; anIndex++ ) { - Handle(HYDROData_Object) aGeomObj = - Handle(HYDROData_Object)::DownCast( theObjectList.Value( anIndex ) ); - if( aGeomObj.IsNull() ) - continue; + Handle(HYDROData_Entity) anObj = theObjectList.Value( anIndex ); + TopoDS_Shape aShape; + + Handle(HYDROData_Object) aGeomObj = Handle(HYDROData_Object)::DownCast( anObj ); + if( !aGeomObj.IsNull() ) { + aShape = aGeomObj->GetTopShape(); + } else { + Handle(HYDROData_LandCover) aLandCoverObj = Handle(HYDROData_LandCover)::DownCast( anObj ); + if ( !aLandCoverObj.IsNull() ) { + aShape = aLandCoverObj->GetShape(); + } + } - TopoDS_Shape aShape = aGeomObj->GetTopShape(); if ( aShape.IsNull() ) continue; #ifdef DEB_SPLIT_TO_ZONES @@ -157,12 +165,12 @@ HYDROData_SplitToZonesTool::SplitDataList for ( ; anExp.More(); anExp.Next() ) { const TopoDS_Face& aFace = TopoDS::Face( anExp.Current() ); if ( !aFace.IsNull() ) { - SplitData aSplitData( SplitData::Data_Zone, aFace, aGeomObj->GetName() ); + SplitData aSplitData( SplitData::Data_Zone, aFace, anObj->GetName() ); anInputSplitDataList.append( aSplitData ); } } } else { - SplitData aSplitData( SplitData::Data_Zone, aShape, aGeomObj->GetName() ); + SplitData aSplitData( SplitData::Data_Zone, aShape, anObj->GetName() ); anInputSplitDataList.append( aSplitData ); } } @@ -596,3 +604,11 @@ HYDROData_SplitToZonesTool::SplitDataList return anOutputSplitDataList; } +HYDROData_SplitToZonesTool::SplitDataList + HYDROData_SplitToZonesTool::Split( const HYDROData_SequenceOfObjects& theObjectList ) +{ + HYDROData_SequenceOfObjects aGeomGroups; + Handle(HYDROData_PolylineXY) aPolyline; + + return Split( theObjectList, aGeomGroups, aPolyline ); +} \ No newline at end of file diff --git a/src/HYDROData/HYDROData_SplitToZonesTool.h b/src/HYDROData/HYDROData_SplitToZonesTool.h index c1a69130..160fba0d 100644 --- a/src/HYDROData/HYDROData_SplitToZonesTool.h +++ b/src/HYDROData/HYDROData_SplitToZonesTool.h @@ -85,6 +85,8 @@ public: const HYDROData_SequenceOfObjects& theGroupsList, const Handle(HYDROData_PolylineXY)& thePolyline ); + static SplitDataList Split( const HYDROData_SequenceOfObjects& theObjectList ); + static void SetFileNames(const QString& theNameBefore, const QString& theNameAfter); private: diff --git a/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx b/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx index c7274371..83249f3c 100644 --- a/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx +++ b/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx @@ -842,13 +842,22 @@ void HYDROGUI_CalculationDlg::setEditedObject( const Handle(HYDROData_Calculatio myValidator->setEditedObject( theCase ); // Build the calculation case subtree - module()->getDataModel()->buildCaseTree( myBrowser->root(), myEditedObject ); - + module()->getDataModel()->buildCaseTree( myBrowser->root(), myEditedObject, false ); + myBrowser->updateTree(); myBrowser->openLevels(); myBrowser->adjustColumnsWidth(); myBrowser->setAutoUpdate( true ); myBrowser->setUpdateModified( true ); + + // Build the calculation case subtree for Land Cover regions + module()->getDataModel()->buildCaseTree( myLandCoverBrowser->root(), myEditedObject, true ); + + myLandCoverBrowser->updateTree(); + myLandCoverBrowser->openLevels(); + myLandCoverBrowser->adjustColumnsWidth(); + myLandCoverBrowser->setAutoUpdate( true ); + myLandCoverBrowser->setUpdateModified( true ); } HYDROGUI_Zone* HYDROGUI_CalculationDlg::getCurrentZone() const @@ -860,14 +869,14 @@ void HYDROGUI_CalculationDlg::refreshZonesBrowser() { SUIT_DataObject* aRoot = myBrowser->root(); module()->getDataModel()->updateObjectTree( myEditedObject ); - module()->getDataModel()->buildCaseTree( aRoot, myEditedObject ); + module()->getDataModel()->buildCaseTree( aRoot, myEditedObject, false ); myBrowser->updateTree( aRoot ); } void HYDROGUI_CalculationDlg::onDataChanged() { SUIT_DataObject* aRoot = myBrowser->root(); - module()->getDataModel()->buildCaseTree( aRoot, myEditedObject ); + module()->getDataModel()->buildCaseTree( aRoot, myEditedObject, false ); myBrowser->updateTree( aRoot ); } @@ -1124,7 +1133,7 @@ void HYDROGUI_CalculationDlg::refreshLandCoverZonesBrowser() { SUIT_DataObject* aRoot = myLandCoverBrowser->root(); module()->getDataModel()->updateObjectTree( myEditedObject ); - module()->getDataModel()->buildCaseTree( aRoot, myEditedObject ); + module()->getDataModel()->buildCaseTree( aRoot, myEditedObject, true ); myLandCoverBrowser->updateTree( aRoot ); } @@ -1134,7 +1143,7 @@ void HYDROGUI_CalculationDlg::refreshLandCoverZonesBrowser() void HYDROGUI_CalculationDlg::onDataLandCoverChanged() { SUIT_DataObject* aRoot = myLandCoverBrowser->root(); - module()->getDataModel()->buildCaseTree( aRoot, myEditedObject ); + module()->getDataModel()->buildCaseTree( aRoot, myEditedObject, true ); myLandCoverBrowser->updateTree( aRoot ); } diff --git a/src/HYDROGUI/HYDROGUI_DataModel.cxx b/src/HYDROGUI/HYDROGUI_DataModel.cxx index 623920a0..1eaef34b 100644 --- a/src/HYDROGUI/HYDROGUI_DataModel.cxx +++ b/src/HYDROGUI/HYDROGUI_DataModel.cxx @@ -995,10 +995,19 @@ void HYDROGUI_DataModel::buildObjectTree( SUIT_DataObject* theParent, createRegion( aCaseRegionsSect, aCaseRegion, "", true, theIsInOperation ); } - // TODO: Build object tree for land cover regions - //HYDROData_SequenceOfObjects aCaseLandCoverRegions = aCaseObj->GetRegions( true ); - //... + LightApp_DataObject* aCaseLandCoverRegionsSect = + createObject( aGuiObj, tr( "CASE_LAND_COVER_REGIONS" ), aGuiObj->entry() ); + HYDROData_SequenceOfObjects aCaseLandCoverRegions = aCaseObj->GetRegions( true ); + anIter.Init( aCaseLandCoverRegions ); + for ( ; anIter.More(); anIter.Next() ) + { + Handle(HYDROData_Region) aCaseLCRegion = + Handle(HYDROData_Region)::DownCast( anIter.Value() ); + if( !aCaseLCRegion.IsNull() && !aCaseLCRegion->IsRemoved() ) + createRegion( aCaseLandCoverRegionsSect, aCaseLCRegion, "", true, theIsInOperation ); + } + #ifdef DEB_GROUPS HYDROData_SequenceOfObjects aCalcGroups = aCaseObj->GetGeometryGroups(); buildObjectPartition( aGuiObj, aCalcGroups, tr( "OBJECT_GROUPS" ), false ); @@ -1071,7 +1080,8 @@ void HYDROGUI_DataModel::buildObjectTree( SUIT_DataObject* theParent, } } -void HYDROGUI_DataModel::buildCaseTree( SUIT_DataObject* theParent, Handle(HYDROData_CalculationCase) theCase ) +void HYDROGUI_DataModel::buildCaseTree( SUIT_DataObject* theParent, Handle(HYDROData_CalculationCase) theCase, + const bool theLandCover ) { if ( !theCase.IsNull() ) { @@ -1087,7 +1097,7 @@ void HYDROGUI_DataModel::buildCaseTree( SUIT_DataObject* theParent, Handle(HYDRO new HYDROGUI_DropTargetObject( theParent, tr( "NEW_REGION" ), "", true ); - HYDROData_SequenceOfObjects aCaseRegions = theCase->GetRegions( false ); + HYDROData_SequenceOfObjects aCaseRegions = theCase->GetRegions( theLandCover ); HYDROData_SequenceOfObjects::Iterator anIter( aCaseRegions ); for ( ; anIter.More(); anIter.Next() ) { @@ -1096,10 +1106,6 @@ void HYDROGUI_DataModel::buildCaseTree( SUIT_DataObject* theParent, Handle(HYDRO if( !aCaseRegion.IsNull() && !aCaseRegion->IsRemoved() ) createRegion( theParent, aCaseRegion, "", true, true ); } - - // TODO: Create land cover regions - //HYDROData_SequenceOfObjects aCaseLandCoverRegions = theCase->GetRegions( true ); - //... } } diff --git a/src/HYDROGUI/HYDROGUI_DataModel.h b/src/HYDROGUI/HYDROGUI_DataModel.h index 6edb11f6..a7e1ed7c 100644 --- a/src/HYDROGUI/HYDROGUI_DataModel.h +++ b/src/HYDROGUI/HYDROGUI_DataModel.h @@ -228,9 +228,11 @@ public: * Creates the Calculation Case subtree for usage within an operation dialog. * \param theParent a created object will be appended as a child of this GUI object * \param theCase the calculation case model object + * \param theLandCover if true - land cover regions will be represented in the tree */ void buildCaseTree( SUIT_DataObject* theParent, - Handle(HYDROData_CalculationCase) theCase ); + Handle(HYDROData_CalculationCase) theCase, + const bool theLandCover ); /** * Updates the object subtree. diff --git a/src/HYDROGUI/resources/HYDROGUI_msg_en.ts b/src/HYDROGUI/resources/HYDROGUI_msg_en.ts index 0e686cdf..0f4218b5 100644 --- a/src/HYDROGUI/resources/HYDROGUI_msg_en.ts +++ b/src/HYDROGUI/resources/HYDROGUI_msg_en.ts @@ -115,6 +115,10 @@ CASE_REGIONS REGIONS + + CASE_LAND_COVER_REGIONS + LAND COVER REGIONS + CASE_SPLITTED_GROUPS Split groups diff --git a/src/HYDROPy/HYDROData_CalculationCase.sip b/src/HYDROPy/HYDROData_CalculationCase.sip index 0579fb9a..afa46a34 100644 --- a/src/HYDROPy/HYDROData_CalculationCase.sip +++ b/src/HYDROPy/HYDROData_CalculationCase.sip @@ -269,7 +269,7 @@ public: /** * Removes reference region from calculation case. */ - void RemoveRegion( HYDROData_Region theRegion ) [void ( const Handle_HYDROData_Region& )]; + void RemoveRegion( HYDROData_Region theRegion, const bool theLandCover ) [void ( const Handle_HYDROData_Region&, const bool )]; %MethodCode Handle(HYDROData_Region) aRef = Handle(HYDROData_Region)::DownCast( createHandle( a0 ) ); @@ -277,9 +277,9 @@ public: { Py_BEGIN_ALLOW_THREADS if ( sipSelfWasArg ) { - sipCpp->HYDROData_CalculationCase::RemoveRegion( aRef ); + sipCpp->HYDROData_CalculationCase::RemoveRegion( aRef, a1 ); } else { - sipCpp->RemoveRegion( aRef ); + sipCpp->RemoveRegion( aRef, a1 ); } Py_END_ALLOW_THREADS } -- 2.39.2