From 7716366a329bf34bc3b659dcf8f8f155b9cb0a2a Mon Sep 17 00:00:00 2001 From: ouv Date: Thu, 19 Sep 2013 13:00:10 +0000 Subject: [PATCH] Split Zones functionality (draft version). --- src/HYDROGUI/CMakeLists.txt | 2 + src/HYDROGUI/HYDROGUI.vcproj | 14 +- src/HYDROGUI/HYDROGUI_Module.h | 2 + src/HYDROGUI/HYDROGUI_Operations.cxx | 105 +++++++++++++++ src/HYDROGUI/HYDROGUI_Operations.h | 2 + src/HYDROGUI/HYDROGUI_PrsPolyline.cxx | 14 ++ src/HYDROGUI/HYDROGUI_PrsZone.cxx | 15 ++- src/HYDROGUI/HYDROGUI_SplitZonesTool.cxx | 161 +++++++++++++++++++++++ src/HYDROGUI/HYDROGUI_SplitZonesTool.h | 66 ++++++++++ 9 files changed, 377 insertions(+), 4 deletions(-) create mode 100644 src/HYDROGUI/HYDROGUI_SplitZonesTool.cxx create mode 100644 src/HYDROGUI/HYDROGUI_SplitZonesTool.h diff --git a/src/HYDROGUI/CMakeLists.txt b/src/HYDROGUI/CMakeLists.txt index c0aee0a0..c8316fea 100644 --- a/src/HYDROGUI/CMakeLists.txt +++ b/src/HYDROGUI/CMakeLists.txt @@ -37,6 +37,7 @@ set(PROJECT_HEADERS HYDROGUI_PrsZoneDriver.h HYDROGUI_Shape.h HYDROGUI_ShowHideOp.h + HYDROGUI_SplitZonesTool.h HYDROGUI_Tool.h HYDROGUI_TwoImagesDlg.h HYDROGUI_TwoImagesOp.h @@ -84,6 +85,7 @@ set(PROJECT_SOURCES HYDROGUI_PrsZoneDriver.cxx HYDROGUI_Shape.cxx HYDROGUI_ShowHideOp.cxx + HYDROGUI_SplitZonesTool.cxx HYDROGUI_Tool.cxx HYDROGUI_TwoImagesDlg.cxx HYDROGUI_TwoImagesOp.cxx diff --git a/src/HYDROGUI/HYDROGUI.vcproj b/src/HYDROGUI/HYDROGUI.vcproj index 15cd7ed8..bc0513be 100644 --- a/src/HYDROGUI/HYDROGUI.vcproj +++ b/src/HYDROGUI/HYDROGUI.vcproj @@ -1,7 +1,7 @@ + + @@ -655,6 +659,10 @@ /> + + @@ -728,7 +736,7 @@ @@ -742,7 +750,7 @@ diff --git a/src/HYDROGUI/HYDROGUI_Module.h b/src/HYDROGUI/HYDROGUI_Module.h index 2fe241ce..2950a9fc 100644 --- a/src/HYDROGUI/HYDROGUI_Module.h +++ b/src/HYDROGUI/HYDROGUI_Module.h @@ -125,6 +125,8 @@ protected slots: void onViewPortMouseEvent( QGraphicsSceneMouseEvent* ); + void onTestSplit(); // ouv: tmp, to delete + private: void updateGV( const bool theIsInit = false, const bool theIsForced = false ); diff --git a/src/HYDROGUI/HYDROGUI_Operations.cxx b/src/HYDROGUI/HYDROGUI_Operations.cxx index 87428aa3..16fc405f 100644 --- a/src/HYDROGUI/HYDROGUI_Operations.cxx +++ b/src/HYDROGUI/HYDROGUI_Operations.cxx @@ -33,6 +33,7 @@ #include "HYDROGUI_ObserveImageOp.h" #include "HYDROGUI_PolylineOp.h" #include "HYDROGUI_ShowHideOp.h" +#include "HYDROGUI_SplitZonesTool.h" #include "HYDROGUI_TwoImagesOp.h" #include "HYDROGUI_UpdateFlags.h" #include "HYDROGUI_UpdateImageOp.h" @@ -136,6 +137,9 @@ void HYDROGUI_Module::createMenus() createMenu( FuseImagesId, aHydroId, -1, -1 ); createMenu( CutImagesId, aHydroId, -1, -1 ); createMenu( SplitImageId, aHydroId, -1, -1 ); + + createMenu( separator(), aHydroId ); + createMenu( TestSplitId, aHydroId, -1, -1 ); } void HYDROGUI_Module::createPopups() @@ -169,6 +173,10 @@ void HYDROGUI_Module::createUndoRedoActions() connect( anEditUndo, SIGNAL( triggered( int ) ), this, SLOT( onUndo( int ) ) ); connect( anEditRedo, SIGNAL( triggered( int ) ), this, SLOT( onRedo( int ) ) ); + + QAction* aTestSplit = new QAction( "Test split", application()->desktop() ); + registerAction( TestSplitId, aTestSplit ); + connect( aTestSplit, SIGNAL( triggered() ), this, SLOT( onTestSplit() ) ); } void HYDROGUI_Module::updateUndoRedoControls() @@ -313,3 +321,100 @@ LightApp_Operation* HYDROGUI_Module::createOperation( const int theId ) const return anOp; } + +//----------------------------------------------------------------------------- +// Test splitting +//----------------------------------------------------------------------------- +#include +#include +void HYDROGUI_Module::onTestSplit() +{ + Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( getStudyId() ); + + aDocument->StartOperation(); + + HYDROData_SequenceOfObjects aZoneList; + HYDROData_Iterator anIterator( aDocument, KIND_ZONE ); + for( ; anIterator.More(); anIterator.Next() ) + aZoneList.Append( anIterator.Current() ); + + HYDROGUI_SplitZonesTool::SplitDataList aSplitDataList = + HYDROGUI_SplitZonesTool::SplitZones( aZoneList ); + + int anIndex = 0; + HYDROGUI_SplitZonesTool::SplitDataListIterator anIter( aSplitDataList ); + while( anIter.hasNext() ) + { + const HYDROGUI_SplitZonesTool::SplitData& aSplitData = anIter.next(); + const QPainterPath& aPath = aSplitData.Path; + const QStringList& aZoneNames = aSplitData.ZoneNames; + + Handle(HYDROData_Polyline) aPolyline = + Handle(HYDROData_Polyline)::DownCast( aDocument->CreateObject( KIND_POLYLINE ) ); + if( !aPolyline.IsNull() ) + { + aPolyline->SetName( QString( "SplitPolyline_%1" ).arg( ++anIndex ) ); + aPolyline->setDimension( 2 ); + + QList aPolylineData; + for( int i = 0, n = aPath.elementCount(); i < n; i++ ) + { + const QPainterPath::Element anElement = aPath.elementAt( i ); + switch( anElement.type ) + { + case QPainterPath::MoveToElement: + aPolylineData.append( PolylineSection() ); + break; + case QPainterPath::LineToElement: + if( !aPolylineData.isEmpty() ) + { + PolylineSection& aSection = aPolylineData.last(); + aSection.myCoords << anElement.x; + aSection.myCoords << anElement.y; + } + break; + case QPainterPath::CurveToElement: // currently not supported + default: + break; + } + } + aPolyline->setPolylineData( aPolylineData ); + } + + Handle(HYDROData_Zone) aZone = + Handle(HYDROData_Zone)::DownCast( aDocument->CreateObject( KIND_ZONE ) ); + if( !aZone.IsNull() ) + { + aZone->SetName( QString( "SplitZone_%1" ).arg( anIndex ) ); + aZone->SetPolyline( aPolyline ); + + aZone->SetBorderColor( Qt::black ); + + int aCounter = 0; + int aR = 0, aG = 0, aB = 0; + QStringListIterator aZoneNameIter( aZoneNames ); + while( aZoneNameIter.hasNext() ) + { + const QString& aZoneName = aZoneNameIter.next(); + Handle(HYDROData_Zone) aRefZone = Handle(HYDROData_Zone)::DownCast( + HYDROGUI_Tool::FindObjectByName( this, aZoneName, KIND_ZONE ) ); + if( !aRefZone.IsNull() ) + { + QColor aRefColor = aRefZone->GetFillingColor(); + aR += aRefColor.red(); + aG += aRefColor.green(); + aB += aRefColor.blue(); + aCounter++; + } + } + if( aCounter > 0 ) + { + QColor aFillingColor( aR / aCounter, aG / aCounter, aB / aCounter ); + aZone->SetFillingColor( aFillingColor ); + } + } + } + + aDocument->CommitOperation(); + update( UF_Model ); +} diff --git a/src/HYDROGUI/HYDROGUI_Operations.h b/src/HYDROGUI/HYDROGUI_Operations.h index c8b8309f..e0cf2f3c 100644 --- a/src/HYDROGUI/HYDROGUI_Operations.h +++ b/src/HYDROGUI/HYDROGUI_Operations.h @@ -70,6 +70,8 @@ enum OperationId ShowAllId, HideId, HideAllId, + + TestSplitId }; #endif diff --git a/src/HYDROGUI/HYDROGUI_PrsPolyline.cxx b/src/HYDROGUI/HYDROGUI_PrsPolyline.cxx index 66005576..57748202 100644 --- a/src/HYDROGUI/HYDROGUI_PrsPolyline.cxx +++ b/src/HYDROGUI/HYDROGUI_PrsPolyline.cxx @@ -22,6 +22,8 @@ #include "HYDROGUI_PrsPolyline.h" +#include + //======================================================================= // name : HYDROGUI_PrsPolyline // Purpose : Constructor @@ -107,6 +109,12 @@ bool HYDROGUI_PrsPolyline::select( double theX, double theY, const QRectF& theRe void HYDROGUI_PrsPolyline::unselect() { GraphicsView_Object::unselect(); + + // ouv: tmp + QPen aPen = myPolylineItem->pen(); + aPen.setColor( Qt::black ); + aPen.setWidth( 1 ); + myPolylineItem->setPen( aPen ); } //================================================================ @@ -116,4 +124,10 @@ void HYDROGUI_PrsPolyline::unselect() void HYDROGUI_PrsPolyline::setSelected( bool theState ) { GraphicsView_Object::setSelected( theState ); + + // ouv: tmp + QPen aPen = myPolylineItem->pen(); + aPen.setColor( theState ? Qt::red : Qt::black ); + aPen.setWidth( theState ? 2 : 1 ); + myPolylineItem->setPen( aPen ); } diff --git a/src/HYDROGUI/HYDROGUI_PrsZone.cxx b/src/HYDROGUI/HYDROGUI_PrsZone.cxx index 3dafc9a2..fc857245 100644 --- a/src/HYDROGUI/HYDROGUI_PrsZone.cxx +++ b/src/HYDROGUI/HYDROGUI_PrsZone.cxx @@ -121,7 +121,8 @@ void HYDROGUI_PrsZone::compute() } QPainterPath aPath( myPath ); - aPath.setFillRule( Qt::WindingFill ); + //aPath.setFillRule( Qt::WindingFill ); + aPath.setFillRule( Qt::OddEvenFill ); // ouv: for correct drawing the paths with holes myZoneItem->setPath( aPath ); myZoneItem->setBrush( QBrush( myFillingColor ) ); @@ -154,6 +155,12 @@ bool HYDROGUI_PrsZone::select( double theX, double theY, const QRectF& theRect ) void HYDROGUI_PrsZone::unselect() { GraphicsView_Object::unselect(); + + // ouv: tmp + QPen aPen = myZoneItem->pen(); + aPen.setColor( Qt::black ); + aPen.setWidth( 1 ); + myZoneItem->setPen( aPen ); } //================================================================ @@ -163,4 +170,10 @@ void HYDROGUI_PrsZone::unselect() void HYDROGUI_PrsZone::setSelected( bool theState ) { GraphicsView_Object::setSelected( theState ); + + // ouv: tmp + QPen aPen = myZoneItem->pen(); + aPen.setColor( theState ? Qt::red : Qt::black ); + aPen.setWidth( theState ? 2 : 1 ); + myZoneItem->setPen( aPen ); } diff --git a/src/HYDROGUI/HYDROGUI_SplitZonesTool.cxx b/src/HYDROGUI/HYDROGUI_SplitZonesTool.cxx new file mode 100644 index 00000000..af490e46 --- /dev/null +++ b/src/HYDROGUI/HYDROGUI_SplitZonesTool.cxx @@ -0,0 +1,161 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "HYDROGUI_SplitZonesTool.h" + +#include + +HYDROGUI_SplitZonesTool::SplitDataList +HYDROGUI_SplitZonesTool::SplitZones( const HYDROData_SequenceOfObjects& theZoneList ) +{ + SplitDataList anOutputSplitDataList; + + SplitDataList anInputSplitDataList; + for( int anIndex = 1, aLength = theZoneList.Length(); anIndex <= aLength; anIndex++ ) + { + Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( theZoneList.Value( anIndex ) ); + if( !aZone.IsNull() ) + { + SplitData aSplitData( aZone->GetPainterPath(), aZone->GetName() ); + anInputSplitDataList.append( aSplitData ); + } + } + + SplitDataListIterator anInputIter( anInputSplitDataList ); + while( anInputIter.hasNext() ) + { + const SplitData& anInputSplitData = anInputIter.next(); + if( anOutputSplitDataList.isEmpty() ) + anOutputSplitDataList.append( anInputSplitData ); + else + { + SplitDataList aSplitDataList; + SplitDataListIterator anOutputIter( anOutputSplitDataList ); + while( anOutputIter.hasNext() ) + { + const SplitData& anOutputSplitData = anOutputIter.next(); + + SplitDataList aList = SplitTwoData( anOutputSplitData, anInputSplitData ); + aSplitDataList.append( aList ); + } + anOutputSplitDataList = aSplitDataList; + } + } + + /* + if( theZoneList.Length() != 2 ) + return aSplitDataList; + + Handle(HYDROData_Zone) aZone1 = Handle(HYDROData_Zone)::DownCast( theZoneList.Value( 1 ) ); + Handle(HYDROData_Zone) aZone2 = Handle(HYDROData_Zone)::DownCast( theZoneList.Value( 2 ) ); + + SplitData aSplitData1( aZone1->GetPainterPath(), aZone1->GetName() ); + SplitData aSplitData2( aZone2->GetPainterPath(), aZone2->GetName() ); + + aSplitDataList = SplitTwoData( aSplitData1, aSplitData2 ); + */ + + return anOutputSplitDataList; +} + +HYDROGUI_SplitZonesTool::SplitDataList +HYDROGUI_SplitZonesTool::SplitTwoData( const SplitData& theData1, + const SplitData& theData2 ) +{ + SplitDataList aSplitDataList; + + const QPainterPath& aPath1 = theData1.Path; + const QPainterPath& aPath2 = theData2.Path; + + const QStringList& aZoneNames1 = theData1.ZoneNames; + const QStringList& aZoneNames2 = theData2.ZoneNames; + + QPainterPath anIntersection = aPath1.intersected( aPath2 ); + if( anIntersection.isEmpty() ) + { + aSplitDataList.append( theData1 ); + aSplitDataList.append( theData2 ); + } + else + { + aSplitDataList.append( SplitData( anIntersection, aZoneNames1 + aZoneNames2 ) ); + + QPainterPath aPath1Sub = aPath1.subtracted( aPath2 ); + if( !aPath1Sub.isEmpty() ) + aSplitDataList.append( ExtractSeparateData( SplitData( aPath1Sub, aZoneNames1 ) ) ); + + QPainterPath aPath2Sub = aPath2.subtracted( aPath1 ); + if( !aPath2Sub.isEmpty() ) + aSplitDataList.append( ExtractSeparateData( SplitData( aPath2Sub, aZoneNames2 ) ) ); + } + return aSplitDataList; +} + +HYDROGUI_SplitZonesTool::SplitDataList +HYDROGUI_SplitZonesTool::ExtractSeparateData( const SplitData& theData ) +{ + SplitDataList aSplitDataList; + + const QPainterPath& aBasePath = theData.Path; + const QStringList& aBaseZoneNames = theData.ZoneNames; + + QList aPathList; + for( int i = 0, n = aBasePath.elementCount(); i < n; i++ ) + { + const QPainterPath::Element anElement = aBasePath.elementAt( i ); + switch( anElement.type ) + { + case QPainterPath::MoveToElement: + aPathList.append( QPainterPath( QPointF( anElement.x, anElement.y ) ) ); + break; + case QPainterPath::LineToElement: + if( !aPathList.isEmpty() ) + { + QPainterPath& aPath = aPathList.last(); + aPath.lineTo( anElement.x, anElement.y ); + } + break; + case QPainterPath::CurveToElement: // currently not supported + default: + break; + } + } + + if( aPathList.size() == 2 ) + { + const QPainterPath& aPath1 = aPathList.first(); + const QPainterPath& aPath2 = aPathList.last(); + if( aPath1.contains( aPath2 ) || aPath2.contains( aPath1 ) ) + { + aSplitDataList.append( theData ); + return aSplitDataList; + } + } + + QListIterator anIter( aPathList ); + while( anIter.hasNext() ) + { + const QPainterPath& aPath = anIter.next(); + aSplitDataList.append( SplitData( aPath, aBaseZoneNames ) ); + } + return aSplitDataList; +} diff --git a/src/HYDROGUI/HYDROGUI_SplitZonesTool.h b/src/HYDROGUI/HYDROGUI_SplitZonesTool.h new file mode 100644 index 00000000..fc8c35c5 --- /dev/null +++ b/src/HYDROGUI/HYDROGUI_SplitZonesTool.h @@ -0,0 +1,66 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef HYDROGUI_SPLITZONESTOOL_H +#define HYDROGUI_SPLITZONESTOOL_H + +#include + +#include +#include + +/** + * \class HYDROGUI_SplitZonesTool + * \brief This class contains methods used for splitting zones + * into non-intersected regions. + */ +class HYDROGUI_SplitZonesTool +{ +public: + struct SplitData + { + QPainterPath Path; + QStringList ZoneNames; + + SplitData( const QPainterPath& thePath, + const QStringList& theZoneNames ) : + Path( thePath ), ZoneNames( theZoneNames ) {} + + SplitData( const QPainterPath& thePath, + const QString& theZoneName ) : + Path( thePath ), ZoneNames( theZoneName ) {} + }; + + typedef QList SplitDataList; + typedef QListIterator SplitDataListIterator; + +public: + static SplitDataList SplitZones( const HYDROData_SequenceOfObjects& theZoneList ); + +private: + static SplitDataList SplitTwoData( const SplitData& theData1, + const SplitData& theData2 ); + + static SplitDataList ExtractSeparateData( const SplitData& theData ); +}; + +#endif -- 2.39.2