1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROGUI_RecognizeContoursOp.h"
21 #include "HYDROGUI_RecognizeContoursDlg.h"
22 #include "HYDROGUI_Module.h"
23 #include "HYDROGUI_Shape.h"
24 #include "HYDROGUI_Tool2.h"
25 #include "HYDROGUI_UpdateFlags.h"
26 #include "HYDROGUI_OCCSelector.h"
27 #include "HYDROGUI_ZLayers.h"
29 #include <HYDROData_Document.h>
30 #include <HYDROData_GeomTool.h>
31 #include <HYDROData_ShapesTool.h>
32 #include <HYDROData_PolylineXY.h>
34 #include <GeometryGUI.h>
35 #include <GeometryGUI_Operations.h>
36 #include <GEOM_Constants.h>
39 #include <OCCViewer_ViewManager.h>
40 #include <OCCViewer_ViewModel.h>
42 #include <SalomeApp_Study.h>
44 #include <LightApp_Application.h>
45 #include <LightApp_DataOwner.h>
46 #include <LightApp_Displayer.h>
47 #include <LightApp_SelectionMgr.h>
49 #include <SUIT_Desktop.h>
50 #include <SUIT_ViewManager.h>
52 #include <BRepBuilderAPI_GTransform.hxx>
53 #include <gp_GTrsf.hxx>
57 #include <QTemporaryFile>
62 HYDROGUI_RecognizeContoursOp::HYDROGUI_RecognizeContoursOp( HYDROGUI_Module* theModule )
63 : HYDROGUI_Operation( theModule ),
66 setName( tr( "CONTOURS_RECOGNITION" ) );
72 HYDROGUI_RecognizeContoursOp::~HYDROGUI_RecognizeContoursOp()
79 void HYDROGUI_RecognizeContoursOp::startOperation()
81 HYDROGUI_Operation::startOperation();
83 // Set preview view manager
84 if ( !getPreviewManager() ) {
85 setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>(
86 module()->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
89 if ( !isApplyAndClose() ) {
93 // Get the selected image
94 myImage = Handle(HYDROData_Image)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
95 if ( myImage.IsNull() ) {
99 QString anImageName = myImage->GetName();
101 // Create temporary graphics file
102 QImage aQImage = myImage->Image();
103 myTmpImageFile = new QTemporaryFile( QDir::tempPath() + QDir::separator() + anImageName );
104 if ( !myTmpImageFile->open() ||
105 !aQImage.save( myTmpImageFile->fileName(), "PNG", 100 ) ) {
110 // Create the input panel
111 HYDROGUI_RecognizeContoursDlg* aPanel =
112 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
119 aPanel->setImageName( anImageName );
122 SalomeApp_Study* aStudy =
123 dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
125 // Get active view manager
126 SUIT_ViewManager* aViewMgr = module()->getApp()->activeViewManager();
128 // Export the selected image to GEOM module
129 if ( aStudy && aViewMgr ) {
130 GEOM::GEOM_Gen_var aGeomEngine = GeometryGUI::GetGeomGen();
132 QString aGeomPictureEntry;
134 HYDROData_GeomTool::createFaceInGEOM( aGeomEngine, aQImage.width(), aQImage.height(),
135 anImageName, aGeomPictureEntry );
137 if ( !aGeomPictureEntry.isEmpty() ) {
138 aStudy->setObjectProperty( aViewMgr->getGlobalId(), aGeomPictureEntry,
139 GEOM::propertyName( GEOM::Texture ), myTmpImageFile->fileName() );
141 // update the object browser
142 module()->getApp()->updateObjectBrowser( true );
144 // browse the published GEOM picture
145 QStringList anEntries;
146 anEntries << aGeomPictureEntry;
147 browseObjects( anEntries );
149 // Add GEOM picture object entry to the list of temporary geom objects
150 myTmpGeomObjects << aGeomPictureEntry;
154 // Activate GEOM module operation
155 LightApp_Application* anApp = module()->getApp();
157 connect( anApp, SIGNAL( operationFinished( const QString&, const QString&, const QStringList& ) ),
158 this, SLOT( onExternalOperationFinished( const QString&, const QString&, const QStringList& ) ) );
160 module()->getApp()->activateOperation( "Geometry", GEOMOp::OpFeatureDetect );
166 void HYDROGUI_RecognizeContoursOp::abortOperation()
168 LightApp_Application* anApp = module()->getApp();
170 anApp->disconnect( this );
175 HYDROGUI_Operation::abortOperation();
180 void HYDROGUI_RecognizeContoursOp::commitOperation()
182 if ( isApplyAndClose() ) {
186 HYDROGUI_Operation::commitOperation();
191 bool HYDROGUI_RecognizeContoursOp::processApply( int& theUpdateFlags,
192 QString& theErrorMsg,
193 QStringList& theBrowseObjectsEntries )
195 // Check the original image
196 if ( myImage.IsNull() ) {
201 HYDROGUI_RecognizeContoursDlg* aPanel =
202 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
207 // Check if contour GEOM object exists
208 if ( myGeomContourEntry.isEmpty() ) {
209 theErrorMsg = tr( "NO_DETECTED_CONTOURS" );
213 // Get selected polylines
214 QStringList aSelectedtPolylines = aPanel->getSelectedtPolylineNames();
215 // Remove the selected polylines from the panel
216 aPanel->removePolylineNames( aSelectedtPolylines );
219 foreach ( QString aName, aSelectedtPolylines ) {
220 TopoDS_Shape aShape = myPolylineShapes.value( aName )->getTopoShape();
221 if ( aShape.IsNull() ) {
225 Handle(HYDROData_PolylineXY) aPolylineObj =
226 Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
228 if( !aPolylineObj.IsNull() ) {
229 aPolylineObj->SetName( aName );
230 aPolylineObj->ImportShape( aShape, false, NULL );
231 aPolylineObj->SetWireColor( HYDROData_PolylineXY::DefaultWireColor() );
233 aPolylineObj->Update();
234 module()->setIsToUpdate( aPolylineObj );
237 // Remove the shape from the map
238 HYDROGUI_Shape* aShapeToDelete = myPolylineShapes.take( aName );
239 delete aShapeToDelete;
242 theUpdateFlags = UF_Model;
249 HYDROGUI_InputPanel* HYDROGUI_RecognizeContoursOp::createInputPanel() const
251 HYDROGUI_InputPanel* aPanel = new HYDROGUI_RecognizeContoursDlg( module(), getName() );
253 connect( aPanel, SIGNAL( selectionChanged( const QStringList& ) ), this, SLOT( onSelectionChanged( const QStringList& ) ) );
259 * Called when the operation perfomed by another module is finished.
260 * \param theModuleName the name of the module which perfomed the operation
261 * \param theOperationName the operation name
262 * \param theEntryList the list of the created objects entries
264 void HYDROGUI_RecognizeContoursOp::onExternalOperationFinished(
265 const QString& theModuleName, const QString& theOperationName,
266 const QStringList& theEntryList )
268 // Process "Geometry" module operations only
269 if ( theModuleName != "Geometry" ) {
273 // Store the operation name
274 myGEOMOpName = theOperationName;
276 // Close the dialog corresponding to the external operation
277 closeExternalOperationDlg();
279 // Erase the GEOM objects
280 LightApp_Displayer().Erase( theEntryList );
282 // Add GEOM object entries to the list of temporary GEOM objects
283 myTmpGeomObjects << theEntryList;
285 if ( theEntryList.count() == 1 ) {
286 myGeomContourEntry = theEntryList.first();
288 // Update the list of polylines
289 updateRecognizedPolylines();
294 Close the GEOM contours detection dialog.
296 void HYDROGUI_RecognizeContoursOp::closeExternalOperationDlg()
298 if ( myGEOMOpName.isEmpty() ) {
302 SUIT_Desktop* aDesktop = module()->getApp()->desktop();
304 QList<QDialog*> aDialogs = aDesktop->findChildren<QDialog*>();
305 foreach ( QDialog* aDlg, aDialogs ) {
306 if ( typeid(*aDlg).name() == myGEOMOpName ) {
315 Update the list of recognized polylines by exploding the GEOM contour object.
317 void HYDROGUI_RecognizeContoursOp::updateRecognizedPolylines()
323 SalomeApp_Study* aStudy =
324 dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
329 // Explode the compound
330 _PTR(SObject) aSObject( aStudy->studyDS()->FindObjectID( qPrintable( myGeomContourEntry ) ) );
332 TopoDS_Shape aShape = GEOMBase::GetShapeFromIOR( aSObject->GetIOR().c_str() );
334 TopTools_SequenceOfShape aSubShapes;
335 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_WIRE, aSubShapes );
336 if ( aSubShapes.Length() < 1 ) {
337 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_EDGE, aSubShapes );
340 Handle(AIS_InteractiveContext) aCtx = NULL;
343 OCCViewer_ViewManager* aViewManager = getPreviewManager();
344 if ( aViewManager ) {
345 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
346 // aViewer->enablePreselection( true );
347 // aViewer->enableSelection( true );
348 aCtx = aViewer->getAISContext();
349 connect( aViewer, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
353 QTransform aTrsf = myImage->Trsf();
354 QImage anImage = myImage->Image();
355 QRectF aRect( QPointF( 0, 0 ), QPointF( anImage.width(), anImage.height() ) );
356 aRect = aTrsf.mapRect( aRect );
357 aTrsf.setMatrix( aTrsf.m11(), aTrsf.m12(), aTrsf.m13(),
358 aTrsf.m21(), -aTrsf.m22(), aTrsf.m23(),
359 aTrsf.m31() + aRect.width() * 0.5, aTrsf.m32 () - aRect.height() * 0.5, aTrsf.m33() );
362 QTransform aTrsf = myImage->Trsf();
363 gp_Mat aMat( aTrsf.m11(), aTrsf.m21(), 0,
364 aTrsf.m12(), -aTrsf.m22(), 0,
366 QImage anImage = myImage->Image();
367 QRectF aRect( QPointF( 0, 0 ), QPointF( anImage.width(), anImage.height() ) );
368 aRect = aTrsf.mapRect( aRect );
369 gp_XYZ aVec( aTrsf.m31() + aRect.width() * 0.5,
370 aTrsf.m32() - aRect.height() * 0.5, 0 );
372 BRepBuilderAPI_GTransform aBuilder( gp_GTrsf( aMat, aVec ) );
375 Handle(HYDROData_PolylineXY) aPolylineObj = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
376 QStringList aNamesList;
377 for ( int i = 1; i <= aSubShapes.Length(); i++ ) {
378 TopoDS_Shape aSubShape = aSubShapes.Value( i );
380 // Transform the sub-shape
381 aPolylineObj->ImportShape( aSubShape, false, NULL );
382 aPolylineObj->Transform( aTrsf );
385 aBuilder.Perform( aSubShape, Standard_True );
386 if ( aBuilder.IsDone() ) {
387 aSubShape = aBuilder.Shape();
390 HYDROGUI_Shape* aShape = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
391 aShape->setShape( aPolylineObj->GetShape(), true, false );
392 aShape->setBorderColor( HYDROData_PolylineXY::DefaultWireColor(), false, false );
394 QString aPrefix = QString("%1_%2_%3").arg( myImage->GetName(), "Contour", QString::number( i ) );
395 QString aName = HYDROGUI_Tool::GenerateObjectName( module(), aPrefix, QStringList(), true );
396 myPolylineShapes.insert( aName, aShape);
400 aPolylineObj->Remove();
402 if ( !aCtx.IsNull() ) {
403 UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, Graphic3d_ZLayerId_TopOSD );
404 aCtx->UpdateCurrentViewer();
408 HYDROGUI_RecognizeContoursDlg* aPanel =
409 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
411 aPanel->setPolylineNames( aNamesList );
419 void HYDROGUI_RecognizeContoursOp::erasePreview()
421 foreach ( HYDROGUI_Shape* aShape, myPolylineShapes ) {
425 myPolylineShapes.clear();
429 Called when selection of the recognized polylines is changed.
431 void HYDROGUI_RecognizeContoursOp::onSelectionChanged( const QStringList& theSelectedNames )
433 Handle(AIS_InteractiveContext) aCtx = NULL;
435 OCCViewer_ViewManager* aViewManager = getPreviewManager();
436 if ( aViewManager ) {
437 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
438 aCtx = aViewer->getAISContext();
442 if ( !aCtx.IsNull() ) {
443 foreach ( QString aName, myPolylineShapes.keys() ) {
444 Handle(AIS_InteractiveObject) anObject =
445 myPolylineShapes.value(aName)->getAISObjects()[0];
447 bool isSelected = theSelectedNames.contains( aName );
448 if ( ( isSelected && !aCtx->IsSelected( anObject) ) ||
449 ( !isSelected && aCtx->IsSelected( anObject) ) ) {
450 aCtx->AddOrRemoveSelected( anObject, Standard_False );
452 // myPolylineShapes[aName]->highlight( isSelected, true );
454 aCtx->UpdateCurrentViewer();
459 Called when selection in the viewer is changed.
461 void HYDROGUI_RecognizeContoursOp::onViewerSelectionChanged()
464 HYDROGUI_RecognizeContoursDlg* aPanel =
465 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
471 OCCViewer_ViewManager* aViewManager = getPreviewManager();
472 Handle(AIS_InteractiveContext) aCtx = NULL;
473 if ( aViewManager ) {
474 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
475 aCtx = aViewer->getAISContext();
479 if ( !aCtx.IsNull() ) {
480 QStringList aSelectedNames;
482 foreach ( QString aName, myPolylineShapes.keys() ) {
483 bool isSelected = aCtx->IsSelected( myPolylineShapes.value(aName)->getAISObjects()[0] );
485 aSelectedNames << aName;
489 aPanel->setSelectedPolylineNames( aSelectedNames );
494 Do the operation data cleanup.
496 void HYDROGUI_RecognizeContoursOp::cleanup()
498 // Close the external operation dialog
499 closeExternalOperationDlg();
504 // Delete temporary image file
505 if ( myTmpImageFile ) {
506 delete myTmpImageFile;
507 myTmpImageFile = NULL;
510 // Delete temporary GEOM objects
511 if ( !myTmpGeomObjects.isEmpty() ) {
512 HYDROGUI_Tool::DeleteGeomObjects( module(), myTmpGeomObjects );
513 // update the object browser
514 module()->getApp()->updateObjectBrowser( true );