1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "HYDROGUI_ImportImageOp.h"
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_ImportImageDlg.h"
27 #include "HYDROGUI_Module.h"
28 #include "HYDROGUI_PrsImage.h"
29 #include "HYDROGUI_Tool.h"
30 #include "HYDROGUI_UpdateFlags.h"
32 #include <HYDROData_Iterator.h>
34 #include <HYDROOperations_Factory.h>
36 #include <GraphicsView_ViewManager.h>
37 #include <GraphicsView_ViewPort.h>
38 #include <GraphicsView_Viewer.h>
40 #include <LightApp_Application.h>
41 #include <LightApp_UpdateFlags.h>
43 HYDROGUI_ImportImageOp::HYDROGUI_ImportImageOp( HYDROGUI_Module* theModule,
44 const bool theIsEdit )
45 : HYDROGUI_Operation( theModule ),
46 myIsEdit( theIsEdit ),
48 myActiveViewManager( 0 ),
49 myPreviewViewManager( 0 ),
52 myPointType( HYDROGUI_PrsImage::None )
54 setName( theIsEdit ? tr( "EDIT_IMPORTED_IMAGE" ) : tr( "IMPORT_IMAGE" ) );
57 HYDROGUI_ImportImageOp::~HYDROGUI_ImportImageOp()
61 void HYDROGUI_ImportImageOp::startOperation()
63 HYDROGUI_Operation::startOperation();
65 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
67 aPanel->setIsEdit( myIsEdit );
71 myEditedObject = Handle(HYDROData_Image)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
72 if( !myEditedObject.IsNull() )
74 QImage anImage = myEditedObject->Image();
76 QPoint aPointA1, aPointB1, aPointC1;
77 QPointF aPointA2, aPointB2, aPointC2;
78 myEditedObject->TrsfPoints( aPointA1, aPointB1, aPointC1,
79 aPointA2, aPointB2, aPointC2 );
81 onCreatePreview( anImage );
85 HYDROGUI_PrsImage::TransformationPointMap aPointMap =
86 myPreviewPrs->getTransformationPointMap();
87 if( !aPointMap.isEmpty() )
89 aPointMap[ HYDROGUI_PrsImage::PointA ].Point = aPointA1;
90 aPointMap[ HYDROGUI_PrsImage::PointB ].Point = aPointB1;
91 aPointMap[ HYDROGUI_PrsImage::PointC ].Point = aPointC1;
92 myPreviewPrs->setTransformationPointMap( aPointMap );
96 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
97 aDataMap[ HYDROGUI_PrsImage::PointA ] =
98 HYDROGUI_ImportImageDlg::TransformationData( aPointA1, aPointA2 );
99 aDataMap[ HYDROGUI_PrsImage::PointB ] =
100 HYDROGUI_ImportImageDlg::TransformationData( aPointB1, aPointB2 );
101 aDataMap[ HYDROGUI_PrsImage::PointC ] =
102 HYDROGUI_ImportImageDlg::TransformationData( aPointC1, aPointC2 );
103 ( (HYDROGUI_ImportImageDlg*)inputPanel() )->setTransformationDataMap( aDataMap );
107 // collect information about existing images
108 HYDROGUI_ImportImageDlg::PrsPointDataList aPrsPointDataList;
109 HYDROData_Iterator anIterator( doc(), KIND_IMAGE );
110 for( ; anIterator.More(); anIterator.Next() )
112 Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast( anIterator.Current() );
113 if( !anImageObj.IsNull() )
115 if( myIsEdit && HYDROGUI_Tool::IsEqual( anImageObj, myEditedObject ) )
118 QPoint aPointA1, aPointB1, aPointC1;
119 QPointF aPointA2, aPointB2, aPointC2;
120 anImageObj->TrsfPoints( aPointA1, aPointB1, aPointC1,
121 aPointA2, aPointB2, aPointC2 );
123 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
124 aDataMap[ HYDROGUI_PrsImage::PointA ] =
125 HYDROGUI_ImportImageDlg::TransformationData( aPointA1, aPointA2 );
126 aDataMap[ HYDROGUI_PrsImage::PointB ] =
127 HYDROGUI_ImportImageDlg::TransformationData( aPointB1, aPointB2 );
128 aDataMap[ HYDROGUI_PrsImage::PointC ] =
129 HYDROGUI_ImportImageDlg::TransformationData( aPointC1, aPointC2 );
131 HYDROGUI_ImportImageDlg::PrsPointData aPrsPointData( anImageObj->GetName(), aDataMap );
132 aPrsPointDataList.append( aPrsPointData );
135 ( (HYDROGUI_ImportImageDlg*)inputPanel() )->setPrsPointDataList( aPrsPointDataList );
138 void HYDROGUI_ImportImageOp::abortOperation()
142 HYDROGUI_Operation::abortOperation();
145 void HYDROGUI_ImportImageOp::commitOperation()
149 HYDROGUI_Operation::commitOperation();
152 HYDROGUI_InputPanel* HYDROGUI_ImportImageOp::createInputPanel() const
154 HYDROGUI_InputPanel* aPanel = new HYDROGUI_ImportImageDlg( module(), getName() );
155 connect( aPanel, SIGNAL( createPreview( QImage ) ),
156 this, SLOT( onCreatePreview( QImage ) ) );
157 connect( aPanel, SIGNAL( activatePointSelection( int ) ),
158 this, SLOT( onActivatePointSelection( int ) ) );
159 connect( aPanel, SIGNAL( pointCoordChanged( bool, int, bool, int ) ),
160 this, SLOT( onPointCoordChanged( bool, int, bool, int ) ) );
161 connect( aPanel, SIGNAL( refImageActivated( const QString& ) ),
162 this, SLOT( onRefImageActivated( const QString& ) ) );
166 bool HYDROGUI_ImportImageOp::processApply( int& theUpdateFlags,
167 QString& theErrorMsg )
169 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
171 QString anImageName = aPanel->getImageName();
172 if( anImageName.isEmpty() )
175 if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anImageName ) )
177 // check that there are no other objects with the same name in the document
178 Handle(HYDROData_Object) anObject = HYDROGUI_Tool::FindObjectByName( module(), anImageName );
179 if( !anObject.IsNull() )
181 theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anImageName );
186 bool anIsRefImage = aPanel->getTransformationMode() == HYDROGUI_ImportImageDlg::RefImage;
188 HYDROGUI_ImportImageDlg::TransformationDataMap aMap;
189 if( !aPanel->getTransformationDataMap( aMap ) )
192 HYDROGUI_ImportImageDlg::TransformationDataMap aRefMap;
193 if( anIsRefImage && !aPanel->getTransformationDataMap( aRefMap, true ) )
196 QPoint aPointA1 = aMap[ HYDROGUI_PrsImage::PointA ].first;
197 QPoint aPointB1 = aMap[ HYDROGUI_PrsImage::PointB ].first;
198 QPoint aPointC1 = aMap[ HYDROGUI_PrsImage::PointC ].first;
200 QPointF aPointA2 = aMap[ HYDROGUI_PrsImage::PointA ].second;
201 QPointF aPointB2 = aMap[ HYDROGUI_PrsImage::PointB ].second;
202 QPointF aPointC2 = aMap[ HYDROGUI_PrsImage::PointC ].second;
204 QPoint aPointA3, aPointB3, aPointC3;
207 aPointA3 = aRefMap[ HYDROGUI_PrsImage::PointA ].first;
208 aPointB3 = aRefMap[ HYDROGUI_PrsImage::PointB ].first;
209 aPointC3 = aRefMap[ HYDROGUI_PrsImage::PointC ].first;
212 int xa1 = aPointA1.x();
213 int ya1 = aPointA1.y();
214 int xb1 = aPointB1.x();
215 int yb1 = aPointB1.y();
216 int xc1 = aPointC1.x();
217 int yc1 = aPointC1.y();
219 double xa2 = aPointA2.x();
220 double ya2 = aPointA2.y();
221 double xb2 = aPointB2.x();
222 double yb2 = aPointB2.y();
223 double xc2 = aPointC2.x();
224 double yc2 = aPointC2.y();
226 int xa3 = aPointA3.x();
227 int ya3 = aPointA3.y();
228 int xb3 = aPointB3.x();
229 int yb3 = aPointB3.y();
230 int xc3 = aPointC3.x();
231 int yc3 = aPointC3.y();
233 // first, check that three input points don't belong to a single line
234 if( ( yb1 - ya1 ) * ( xc1 - xa1 ) == ( yc1 - ya1 ) * ( xb1 - xa1 ) )
236 theErrorMsg = tr( "POINTS_A_B_C_BELONG_TO_SINGLE_LINE" );
240 // the same check for the reference points
241 if( anIsRefImage && ( ( yb3 - ya3 ) * ( xc3 - xa3 ) == ( yc3 - ya3 ) * ( xb3 - xa3 ) ) )
243 theErrorMsg = tr( "REFERENCE_POINTS_A_B_C_BELONG_TO_SINGLE_LINE" );
247 QTransform aTransform1( xa1, ya1, 1, xb1, yb1, 1, xc1, yc1, 1 );
248 QTransform aTransform2( xa2, ya2, 1, xb2, yb2, 1, xc2, yc2, 1 );
249 QTransform aTransform3( xa3, ya3, 1, xb3, yb3, 1, xc3, yc3, 1 );
251 bool anIsInvertible = false;
252 QTransform aTransform1Inverted = aTransform1.inverted( &anIsInvertible );
253 if( !anIsInvertible )
255 theErrorMsg = tr( "TRANSFORMATION_MATRIX_CANNOT_BE_COMPUTED" );
259 QTransform aTransform;
261 aTransform = aTransform1Inverted * aTransform3 * myRefTransform;
263 aTransform = aTransform1Inverted * aTransform2;
265 Handle(HYDROData_Image) anImageObj;
267 anImageObj = myEditedObject;
269 anImageObj = Handle(HYDROData_Image)::DownCast( doc()->CreateObject( KIND_IMAGE ) );
271 if( anImageObj.IsNull() )
274 anImageObj->SetName( anImageName );
276 anImageObj->SetImage( myImage );
277 anImageObj->SetTrsf( aTransform );
281 aPointA2 = QPointF( aTransform.map( aPointA1 ) );
282 aPointB2 = QPointF( aTransform.map( aPointB1 ) );
283 aPointC2 = QPointF( aTransform.map( aPointC1 ) );
286 anImageObj->SetTrsfPoints( aPointA1, aPointB1, aPointC1,
287 aPointA2, aPointB2, aPointC2 );
291 // Set imported file name for image
292 QString aFilePath = aPanel->getFileName();
293 anImageObj->SetFilePath( aFilePath );
296 // must be done after all checks and before calling SetVisible() method below
300 module()->setObjectVisible( HYDROGUI_Tool::GetActiveGraphicsViewId( module() ), anImageObj, true );
303 anImageObj->Update();
305 theUpdateFlags = UF_Model | UF_Viewer | UF_GV_Forced;
309 void HYDROGUI_ImportImageOp::onCreatePreview( QImage theImage )
313 LightApp_Application* anApp = module()->getApp();
315 myActiveViewManager = anApp->activeViewManager();
317 myPreviewPrs = new HYDROGUI_PrsImage( myIsEdit ? myEditedObject : 0 );
318 myPreviewPrs->setImage( myImage );
319 myPreviewPrs->compute();
321 myPreviewViewManager =
322 dynamic_cast<GraphicsView_ViewManager*>( anApp->createViewManager( GraphicsView_Viewer::Type() ) );
323 if( myPreviewViewManager )
325 connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
326 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
328 module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_TransformImage );
329 myPreviewViewManager->setTitle( tr( "TRANSFORM_IMAGE" ) );
330 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
332 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
334 //aViewPort->setMousePositionEnabled( true ); //ouv: temporarily commented
336 aViewPort->addItem( myPreviewPrs );
339 myPreviewPrs->setIsTransformationPointPreview( true );
341 connect( aViewer, SIGNAL( selectionChanged( GV_SelectionChangeStatus ) ),
342 this, SLOT( onPointSelected() ) );
346 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
351 if( !myEditedObject.IsNull() )
352 anImageName = myEditedObject->GetName();
355 anImageName = HYDROGUI_Tool::GenerateObjectName( module(), "Image" );
356 aPanel->setImageName( anImageName );
358 aPanel->setImageSize( myImage.size() );
360 aPanel->initializePointSelection();
361 onPointSelected( false );
364 void HYDROGUI_ImportImageOp::onActivatePointSelection( int thePointType )
366 myPointType = thePointType;
368 myPreviewPrs->setTransformationPointType( thePointType );
369 if( myRefPreviewPrs )
370 myRefPreviewPrs->setTransformationPointType( thePointType );
373 void HYDROGUI_ImportImageOp::onPointCoordChanged( bool theIsRef,
378 if( !theIsRef && myPreviewPrs )
379 myPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
380 else if( theIsRef && myRefPreviewPrs )
381 myRefPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
384 void HYDROGUI_ImportImageOp::onRefImageActivated( const QString& theName )
386 myRefTransform.reset();
388 GraphicsView_ViewPort* aViewPort = 0;
389 if( myPreviewViewManager )
390 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
391 aViewPort = aViewer->getActiveViewPort();
397 myPreviewPrs->setCaption( QString() );
399 if( myRefPreviewPrs )
401 myRefPreviewPrs->setCaption( QString() );
402 aViewPort->removeItem( myRefPreviewPrs );
404 delete myRefPreviewPrs;
409 Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast(
410 HYDROGUI_Tool::FindObjectByName( module(), theName, KIND_IMAGE ) );
411 if( !anImageObj.IsNull() )
413 anImage = anImageObj->Image();
414 myRefTransform = anImageObj->Trsf();
416 myRefPreviewPrs = new HYDROGUI_PrsImage( anImageObj );
417 myRefPreviewPrs->setImage( anImage );
418 myRefPreviewPrs->compute();
420 myRefPreviewPrs->setIsTransformationPointPreview( true );
421 myRefPreviewPrs->setTransformationPointType( myPointType );
423 // vertically shift the reference prs relatively to the main prs
426 myPreviewPrs->setCaption( tr( "IMPORTED_IMAGE" ) );
428 QImage anImage = myPreviewPrs->getImage();
429 myRefPreviewPrs->moveBy( 0, anImage.height() + 60 );
430 myRefPreviewPrs->setCaption( tr( "REFERENCE_IMAGE" ) );
433 aViewPort->addItem( myRefPreviewPrs );
438 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
440 aPanel->setImageSize( anImage.size(), true );
442 aPanel->initializePointSelection();
443 onPointSelected( true );
446 void HYDROGUI_ImportImageOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
451 void HYDROGUI_ImportImageOp::onPointSelected()
453 onPointSelected( myRefPreviewPrs && myRefPreviewPrs->isSelected() );
456 void HYDROGUI_ImportImageOp::onPointSelected( bool theIsRefImage )
458 HYDROGUI_PrsImage* aPrs = theIsRefImage ? myRefPreviewPrs : myPreviewPrs;
462 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
464 const HYDROGUI_PrsImage::TransformationPointMap& aPointMap =
465 aPrs->getTransformationPointMap();
466 HYDROGUI_PrsImage::TransformationPointMapIterator anIter( aPointMap );
467 while( anIter.hasNext() )
469 int aPointType = anIter.next().key();
470 const HYDROGUI_PrsImage::TransformationPoint& aTransformationPoint = anIter.value();
471 const QPoint& aPoint = aTransformationPoint.Point;
473 HYDROGUI_ImportImageDlg::TransformationData aData( aPoint, QPointF() );
474 aDataMap[ aPointType ] = aData;
477 ( (HYDROGUI_ImportImageDlg*)inputPanel() )->setTransformationDataMap( aDataMap, true, theIsRefImage );
480 void HYDROGUI_ImportImageOp::closePreview()
482 // It's very strange, but without calling this method (it's quite safe) a crash is stably reproduced.
483 // Scenario: create any non-Graphics view, activate import op, click apply.
484 // Result: a few SIGSEGVs coming from processEvents(), then crash.
485 if( myPreviewViewManager )
486 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
487 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
488 aViewPort->onBoundingRectChanged();
496 if( myRefPreviewPrs )
498 delete myRefPreviewPrs;
502 if( myPreviewViewManager )
504 disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
505 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
507 module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
508 myPreviewViewManager = 0;
511 if( myActiveViewManager )
512 HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );