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>
33 #include <HYDROData_Lambert93.h>
35 #include <HYDROOperations_Factory.h>
37 #include <GraphicsView_ViewManager.h>
38 #include <GraphicsView_ViewPort.h>
39 #include <GraphicsView_Viewer.h>
41 #include <LightApp_Application.h>
42 #include <LightApp_UpdateFlags.h>
44 HYDROGUI_ImportImageOp::HYDROGUI_ImportImageOp( HYDROGUI_Module* theModule,
45 const bool theIsEdit )
46 : HYDROGUI_Operation( theModule ),
47 myIsEdit( theIsEdit ),
49 myActiveViewManager( 0 ),
50 myPreviewViewManager( 0 ),
53 myPointType( HYDROGUI_PrsImage::None )
55 setName( theIsEdit ? tr( "EDIT_IMPORTED_IMAGE" ) : tr( "IMPORT_IMAGE" ) );
58 HYDROGUI_ImportImageOp::~HYDROGUI_ImportImageOp()
62 void HYDROGUI_ImportImageOp::startOperation()
64 HYDROGUI_Operation::startOperation();
66 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
68 aPanel->setIsEdit( myIsEdit );
72 myEditedObject = Handle(HYDROData_Image)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
73 if( !myEditedObject.IsNull() )
75 QImage anImage = myEditedObject->Image();
77 int aTransformationMode = myEditedObject->TrsfMode();
78 if( aTransformationMode == HYDROGUI_ImportImageDlg::RefImage )
79 aTransformationMode = HYDROGUI_ImportImageDlg::ManualCartesian;
80 aPanel->setTransformationMode( aTransformationMode );
82 QPoint aPointA1, aPointB1, aPointC1;
83 QPointF aPointA2, aPointB2, aPointC2;
84 QPointF aPointA3, aPointB3, aPointC3;
85 myEditedObject->TrsfPoints( aPointA1, aPointB1, aPointC1,
86 aPointA2, aPointB2, aPointC2,
87 aPointA3, aPointB3, aPointC3 );
89 onCreatePreview( anImage );
93 HYDROGUI_PrsImage::TransformationPointMap aPointMap =
94 myPreviewPrs->getTransformationPointMap();
95 if( !aPointMap.isEmpty() )
97 aPointMap[ HYDROGUI_PrsImage::PointA ].Point = aPointA1;
98 aPointMap[ HYDROGUI_PrsImage::PointB ].Point = aPointB1;
99 aPointMap[ HYDROGUI_PrsImage::PointC ].Point = aPointC1;
100 myPreviewPrs->setTransformationPointMap( aPointMap );
104 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
105 aDataMap[ HYDROGUI_PrsImage::PointA ] =
106 HYDROGUI_ImportImageDlg::TransformationData( aPointA1, aPointA2, aPointA3 );
107 aDataMap[ HYDROGUI_PrsImage::PointB ] =
108 HYDROGUI_ImportImageDlg::TransformationData( aPointB1, aPointB2, aPointB3 );
109 aDataMap[ HYDROGUI_PrsImage::PointC ] =
110 HYDROGUI_ImportImageDlg::TransformationData( aPointC1, aPointC2, aPointC3 );
111 aPanel->setTransformationDataMap( aDataMap );
115 // collect information about existing images
116 HYDROGUI_ImportImageDlg::PrsPointDataList aPrsPointDataList;
117 HYDROData_Iterator anIterator( doc(), KIND_IMAGE );
118 for( ; anIterator.More(); anIterator.Next() )
120 Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast( anIterator.Current() );
121 if( !anImageObj.IsNull() )
123 if( myIsEdit && HYDROGUI_Tool::IsEqual( anImageObj, myEditedObject ) )
126 QPoint aPointA1, aPointB1, aPointC1;
127 QPointF aPointA2, aPointB2, aPointC2;
128 QPointF aPointA3, aPointB3, aPointC3;
129 anImageObj->TrsfPoints( aPointA1, aPointB1, aPointC1,
130 aPointA2, aPointB2, aPointC2,
131 aPointA3, aPointB3, aPointC3 );
133 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
134 aDataMap[ HYDROGUI_PrsImage::PointA ] =
135 HYDROGUI_ImportImageDlg::TransformationData( aPointA1, aPointA2, aPointA3 );
136 aDataMap[ HYDROGUI_PrsImage::PointB ] =
137 HYDROGUI_ImportImageDlg::TransformationData( aPointB1, aPointB2, aPointB3 );
138 aDataMap[ HYDROGUI_PrsImage::PointC ] =
139 HYDROGUI_ImportImageDlg::TransformationData( aPointC1, aPointC2, aPointC3 );
141 HYDROGUI_ImportImageDlg::PrsPointData aPrsPointData( anImageObj->GetName(), aDataMap );
142 aPrsPointDataList.append( aPrsPointData );
145 aPanel->setPrsPointDataList( aPrsPointDataList );
148 void HYDROGUI_ImportImageOp::abortOperation()
152 HYDROGUI_Operation::abortOperation();
155 void HYDROGUI_ImportImageOp::commitOperation()
159 HYDROGUI_Operation::commitOperation();
162 HYDROGUI_InputPanel* HYDROGUI_ImportImageOp::createInputPanel() const
164 HYDROGUI_InputPanel* aPanel = new HYDROGUI_ImportImageDlg( module(), getName() );
165 connect( aPanel, SIGNAL( createPreview( QImage ) ),
166 this, SLOT( onCreatePreview( QImage ) ) );
167 connect( aPanel, SIGNAL( activatePointSelection( int ) ),
168 this, SLOT( onActivatePointSelection( int ) ) );
169 connect( aPanel, SIGNAL( pointCoordChanged( bool, int, bool, int ) ),
170 this, SLOT( onPointCoordChanged( bool, int, bool, int ) ) );
171 connect( aPanel, SIGNAL( modeActivated( int ) ),
172 this, SLOT( onModeActivated( int ) ) );
173 connect( aPanel, SIGNAL( refImageActivated( const QString& ) ),
174 this, SLOT( onRefImageActivated( const QString& ) ) );
178 bool HYDROGUI_ImportImageOp::processApply( int& theUpdateFlags,
179 QString& theErrorMsg )
181 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
183 QString anImageName = aPanel->getImageName();
184 if( anImageName.isEmpty() )
187 if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anImageName ) )
189 // check that there are no other objects with the same name in the document
190 Handle(HYDROData_Object) anObject = HYDROGUI_Tool::FindObjectByName( module(), anImageName );
191 if( !anObject.IsNull() )
193 theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anImageName );
198 int aTransformationMode = aPanel->getTransformationMode();
199 bool anIsRefImage = aTransformationMode == HYDROGUI_ImportImageDlg::RefImage;
201 HYDROGUI_ImportImageDlg::TransformationDataMap aMap;
202 if( !aPanel->getTransformationDataMap( aMap ) )
205 HYDROGUI_ImportImageDlg::TransformationDataMap aRefMap;
206 if( anIsRefImage && !aPanel->getTransformationDataMap( aRefMap, true ) )
209 QPoint aPointA = aMap[ HYDROGUI_PrsImage::PointA ].ImagePoint;
210 QPoint aPointB = aMap[ HYDROGUI_PrsImage::PointB ].ImagePoint;
211 QPoint aPointC = aMap[ HYDROGUI_PrsImage::PointC ].ImagePoint;
213 QPointF aLPointA = aMap[ HYDROGUI_PrsImage::PointA ].LambertPoint;
214 QPointF aLPointB = aMap[ HYDROGUI_PrsImage::PointB ].LambertPoint;
215 QPointF aLPointC = aMap[ HYDROGUI_PrsImage::PointC ].LambertPoint;
217 QPointF aCPointA = aMap[ HYDROGUI_PrsImage::PointA ].CartesianPoint;
218 QPointF aCPointB = aMap[ HYDROGUI_PrsImage::PointB ].CartesianPoint;
219 QPointF aCPointC = aMap[ HYDROGUI_PrsImage::PointC ].CartesianPoint;
221 QPoint aRefPointA, aRefPointB, aRefPointC;
224 aRefPointA = aRefMap[ HYDROGUI_PrsImage::PointA ].ImagePoint;
225 aRefPointB = aRefMap[ HYDROGUI_PrsImage::PointB ].ImagePoint;
226 aRefPointC = aRefMap[ HYDROGUI_PrsImage::PointC ].ImagePoint;
229 int xa = aPointA.x();
230 int ya = aPointA.y();
231 int xb = aPointB.x();
232 int yb = aPointB.y();
233 int xc = aPointC.x();
234 int yc = aPointC.y();
236 double xca = aCPointA.x();
237 double yca = aCPointA.y();
238 double xcb = aCPointB.x();
239 double ycb = aCPointB.y();
240 double xcc = aCPointC.x();
241 double ycc = aCPointC.y();
243 int xra = aRefPointA.x();
244 int yra = aRefPointA.y();
245 int xrb = aRefPointB.x();
246 int yrb = aRefPointB.y();
247 int xrc = aRefPointC.x();
248 int yrc = aRefPointC.y();
250 // first, check that three input points don't belong to a single line
251 if( ( yb - ya ) * ( xc - xa ) == ( yc - ya ) * ( xb - xa ) )
253 theErrorMsg = tr( "POINTS_A_B_C_BELONG_TO_SINGLE_LINE" );
257 // the same check for the reference points
259 ( ( yrb - yra ) * ( xrc - xra ) == ( yrc - yra ) * ( xrb - xra ) ) )
261 theErrorMsg = tr( "REFERENCE_POINTS_A_B_C_BELONG_TO_SINGLE_LINE" );
265 QTransform aTransform1( xa, ya, 1, xb, yb, 1, xc, yc, 1 );
266 QTransform aTransform2( xca, yca, 1, xcb, ycb, 1, xcc, ycc, 1 );
267 QTransform aTransform3( xra, yra, 1, xrb, yrb, 1, xrc, yrc, 1 );
269 bool anIsInvertible = false;
270 QTransform aTransform1Inverted = aTransform1.inverted( &anIsInvertible );
271 if( !anIsInvertible )
273 theErrorMsg = tr( "TRANSFORMATION_MATRIX_CANNOT_BE_COMPUTED" );
277 QTransform aTransform;
279 aTransform = aTransform1Inverted * aTransform3 * myRefTransform;
281 aTransform = aTransform1Inverted * aTransform2;
283 Handle(HYDROData_Image) anImageObj;
285 anImageObj = myEditedObject;
287 anImageObj = Handle(HYDROData_Image)::DownCast( doc()->CreateObject( KIND_IMAGE ) );
289 if( anImageObj.IsNull() )
292 anImageObj->SetName( anImageName );
294 anImageObj->SetImage( myImage );
295 anImageObj->SetTrsf( aTransform );
299 aCPointA = QPointF( aTransform.map( aPointA ) );
300 aCPointB = QPointF( aTransform.map( aPointB ) );
301 aCPointC = QPointF( aTransform.map( aPointC ) );
303 // compute Lambert93 points
311 double xla = 0, yla = 0, xlb = 0, ylb = 0, xlc = 0, ylc = 0;
312 HYDROData_Lambert93::toGeo( xca, yca, yla, xla );
313 HYDROData_Lambert93::toGeo( xcb, ycb, ylb, xlb );
314 HYDROData_Lambert93::toGeo( xcc, ycc, ylc, xlc );
316 aLPointA = QPointF( xla * 3600.0, yla * 3600.0 ); // convert degrees to seconds
317 aLPointB = QPointF( xlb * 3600.0, ylb * 3600.0 ); // convert degrees to seconds
318 aLPointC = QPointF( xlc * 3600.0, ylc * 3600.0 ); // convert degrees to seconds
321 anImageObj->SetTrsfMode( aTransformationMode );
322 anImageObj->SetTrsfPoints( aPointA, aPointB, aPointC,
323 aLPointA, aLPointB, aLPointC,
324 aCPointA, aCPointB, aCPointC );
328 // Set imported file name for image
329 QString aFilePath = aPanel->getFileName();
330 anImageObj->SetFilePath( aFilePath );
333 // must be done after all checks and before calling SetVisible() method below
337 module()->setObjectVisible( HYDROGUI_Tool::GetActiveGraphicsViewId( module() ), anImageObj, true );
340 anImageObj->Update();
342 theUpdateFlags = UF_Model | UF_Viewer | UF_GV_Forced | UF_OCCViewer | UF_OCC_Forced;
346 void HYDROGUI_ImportImageOp::onCreatePreview( QImage theImage )
348 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
352 if( myPreviewPrs ) // if the image is changed by choosing another file
354 myPreviewPrs->setImage( myImage );
355 myPreviewPrs->compute();
357 if( myPreviewViewManager )
359 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
361 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
363 aViewPort->onBoundingRectChanged();
371 LightApp_Application* anApp = module()->getApp();
373 myActiveViewManager = anApp->activeViewManager();
375 myPreviewPrs = new HYDROGUI_PrsImage( myIsEdit ? myEditedObject : 0 );
376 myPreviewPrs->setImage( myImage );
377 myPreviewPrs->compute();
379 myPreviewViewManager =
380 dynamic_cast<GraphicsView_ViewManager*>( anApp->createViewManager( GraphicsView_Viewer::Type() ) );
381 if( myPreviewViewManager )
383 connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
384 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
386 module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_TransformImage );
387 myPreviewViewManager->setTitle( tr( "TRANSFORM_IMAGE" ) );
388 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
390 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
392 //aViewPort->setMousePositionEnabled( true ); //ouv: temporarily commented
394 aViewPort->addItem( myPreviewPrs );
397 myPreviewPrs->setIsTransformationPointPreview( true );
399 connect( aViewer, SIGNAL( selectionChanged( GV_SelectionChangeStatus ) ),
400 this, SLOT( onPointSelected() ) );
407 if( !myEditedObject.IsNull() )
408 anImageName = myEditedObject->GetName();
411 anImageName = HYDROGUI_Tool::GenerateObjectName( module(), "Image" );
412 aPanel->setImageName( anImageName );
415 aPanel->setImageSize( myImage.size() );
417 aPanel->initializePointSelection();
418 onPointSelected( false );
421 void HYDROGUI_ImportImageOp::onActivatePointSelection( int thePointType )
423 myPointType = thePointType;
425 myPreviewPrs->setTransformationPointType( thePointType );
426 if( myRefPreviewPrs )
427 myRefPreviewPrs->setTransformationPointType( thePointType );
430 void HYDROGUI_ImportImageOp::onPointCoordChanged( bool theIsRef,
435 if( !theIsRef && myPreviewPrs )
436 myPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
437 else if( theIsRef && myRefPreviewPrs )
438 myRefPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
441 void HYDROGUI_ImportImageOp::onModeActivated( int theMode )
443 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
445 QString aRefImageName;
446 if( theMode == HYDROGUI_ImportImageDlg::RefImage )
448 aRefImageName = aPanel->getRefImageName();
449 if( aRefImageName.isEmpty() )
450 return; // do nothing in this case to avoid visual moving of preview prs
452 onRefImageActivated( aRefImageName );
455 void HYDROGUI_ImportImageOp::onRefImageActivated( const QString& theName )
457 myRefTransform.reset();
459 GraphicsView_ViewPort* aViewPort = 0;
460 if( myPreviewViewManager )
461 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
462 aViewPort = aViewer->getActiveViewPort();
468 myPreviewPrs->setCaption( QString() );
470 if( myRefPreviewPrs )
472 myRefPreviewPrs->setCaption( QString() );
473 aViewPort->removeItem( myRefPreviewPrs );
475 delete myRefPreviewPrs;
480 Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast(
481 HYDROGUI_Tool::FindObjectByName( module(), theName, KIND_IMAGE ) );
482 if( !anImageObj.IsNull() )
484 anImage = anImageObj->Image();
485 myRefTransform = anImageObj->Trsf();
487 myRefPreviewPrs = new HYDROGUI_PrsImage( anImageObj );
488 myRefPreviewPrs->setImage( anImage );
489 myRefPreviewPrs->compute();
491 myRefPreviewPrs->setIsTransformationPointPreview( true );
492 myRefPreviewPrs->setTransformationPointType( myPointType );
494 // vertically shift the reference prs relatively to the main prs
497 myPreviewPrs->setCaption( tr( "IMPORTED_IMAGE" ) );
499 QImage anImage = myPreviewPrs->getImage();
500 myRefPreviewPrs->moveBy( 0, anImage.height() + 60 );
501 myRefPreviewPrs->setCaption( tr( "REFERENCE_IMAGE" ) );
504 aViewPort->addItem( myRefPreviewPrs );
509 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
511 aPanel->setImageSize( anImage.size(), true );
513 aPanel->initializePointSelection();
514 onPointSelected( true );
517 void HYDROGUI_ImportImageOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
522 void HYDROGUI_ImportImageOp::onPointSelected()
524 onPointSelected( myRefPreviewPrs && myRefPreviewPrs->isSelected() );
527 void HYDROGUI_ImportImageOp::onPointSelected( bool theIsRefImage )
529 HYDROGUI_PrsImage* aPrs = theIsRefImage ? myRefPreviewPrs : myPreviewPrs;
533 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
535 const HYDROGUI_PrsImage::TransformationPointMap& aPointMap =
536 aPrs->getTransformationPointMap();
537 HYDROGUI_PrsImage::TransformationPointMapIterator anIter( aPointMap );
538 while( anIter.hasNext() )
540 int aPointType = anIter.next().key();
541 const HYDROGUI_PrsImage::TransformationPoint& aTransformationPoint = anIter.value();
542 const QPoint& aPoint = aTransformationPoint.Point;
544 HYDROGUI_ImportImageDlg::TransformationData aData( aPoint, QPointF(), QPointF() );
545 aDataMap[ aPointType ] = aData;
548 ( (HYDROGUI_ImportImageDlg*)inputPanel() )->setTransformationDataMap( aDataMap, true, theIsRefImage );
551 void HYDROGUI_ImportImageOp::closePreview()
553 // It's very strange, but without calling this method (it's quite safe) a crash is stably reproduced.
554 // Scenario: create any non-Graphics view, activate import op, click apply.
555 // Result: a few SIGSEGVs coming from processEvents(), then crash.
556 if( myPreviewViewManager )
557 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
558 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
559 aViewPort->onBoundingRectChanged();
567 if( myRefPreviewPrs )
569 delete myRefPreviewPrs;
573 if( myPreviewViewManager )
575 disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
576 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
578 module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
579 myPreviewViewManager = 0;
582 if( myActiveViewManager )
583 HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );