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_Tool.h"
25 #include "HYDROGUI_UpdateFlags.h"
26 #include "HYDROGUI_OCCSelector.h"
28 #include <HYDROData_Document.h>
29 #include <HYDROData_GeomTool.h>
30 #include <HYDROData_ShapesTool.h>
31 #include <HYDROData_PolylineXY.h>
33 #include <GeometryGUI.h>
34 #include <GeometryGUI_Operations.h>
35 #include <GEOM_Constants.h>
38 #include <OCCViewer_ViewManager.h>
39 #include <OCCViewer_ViewModel.h>
41 #include <SalomeApp_Study.h>
43 #include <LightApp_Application.h>
44 #include <LightApp_DataOwner.h>
45 #include <LightApp_Displayer.h>
46 #include <LightApp_SelectionMgr.h>
48 #include <SUIT_Desktop.h>
49 #include <SUIT_ViewManager.h>
51 #include <BRepBuilderAPI_GTransform.hxx>
52 #include <gp_GTrsf.hxx>
55 #include <QTemporaryFile>
60 HYDROGUI_RecognizeContoursOp::HYDROGUI_RecognizeContoursOp( HYDROGUI_Module* theModule )
61 : HYDROGUI_Operation( theModule ),
64 setName( tr( "CONTOURS_RECOGNITION" ) );
70 HYDROGUI_RecognizeContoursOp::~HYDROGUI_RecognizeContoursOp()
77 void HYDROGUI_RecognizeContoursOp::startOperation()
79 HYDROGUI_Operation::startOperation();
81 if ( !isApplyAndClose() ) {
85 // Get the selected image
86 myImage = Handle(HYDROData_Image)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
87 if ( myImage.IsNull() ) {
91 QString anImageName = myImage->GetName();
93 // Create temporary graphics file
94 QImage aQImage = myImage->Image();
95 myTmpImageFile = new QTemporaryFile( anImageName );
96 if ( !myTmpImageFile->open() ||
97 !aQImage.save( myTmpImageFile->fileName(), "PNG", 100 ) ) {
102 // Create the input panel
103 HYDROGUI_RecognizeContoursDlg* aPanel =
104 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
111 aPanel->setImageName( anImageName );
114 SalomeApp_Study* aStudy =
115 dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
117 // Get active view manager
118 SUIT_ViewManager* aViewMgr = module()->getApp()->activeViewManager();
120 // Export the selected image to GEOM module
121 if ( aStudy && aViewMgr ) {
122 SALOMEDS::Study_var aDSStudy = GeometryGUI::ClientStudyToStudy( aStudy->studyDS() );
123 GEOM::GEOM_Gen_var aGeomEngine = GeometryGUI::GetGeomGen();
125 QString aGeomPictureEntry;
127 HYDROData_GeomTool::createFaceInGEOM( aGeomEngine, aDSStudy, aQImage.width(), aQImage.height(),
128 anImageName, aGeomPictureEntry );
130 if ( !aGeomPictureEntry.isEmpty() ) {
131 aStudy->setObjectProperty( aViewMgr->getGlobalId(), aGeomPictureEntry,
132 GEOM::propertyName( GEOM::Texture ), myTmpImageFile->fileName() );
134 // update the object browser
135 module()->getApp()->updateObjectBrowser( true );
137 // select the picture
138 SUIT_DataOwnerPtrList aList( true );
139 aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aGeomPictureEntry ) ) );
140 selectionMgr()->setSelected(aList );
142 // Add GEOM picture object entry to the list of temporary geom objects
143 myTmpGeomObjects << aGeomPictureEntry;
147 // Activate GEOM module operation
148 LightApp_Application* anApp = module()->getApp();
150 connect( anApp, SIGNAL( operationFinished( const QString&, const QString&, const QStringList& ) ),
151 this, SLOT( onExternalOperationFinished( const QString&, const QString&, const QStringList& ) ) );
153 module()->getApp()->activateOperation( "Geometry", GEOMOp::OpFeatureDetect );
159 void HYDROGUI_RecognizeContoursOp::abortOperation()
161 LightApp_Application* anApp = module()->getApp();
163 anApp->disconnect( this );
168 HYDROGUI_Operation::abortOperation();
173 void HYDROGUI_RecognizeContoursOp::commitOperation()
175 if ( isApplyAndClose() ) {
179 HYDROGUI_Operation::commitOperation();
184 bool HYDROGUI_RecognizeContoursOp::processApply( int& theUpdateFlags,
185 QString& theErrorMsg,
186 QStringList& theBrowseObjectsEntries )
188 // Check the original image
189 if ( myImage.IsNull() ) {
194 HYDROGUI_RecognizeContoursDlg* aPanel =
195 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
200 // Check if contour GEOM object exists
201 if ( myGeomContourEntry.isEmpty() ) {
202 theErrorMsg = tr( "NO_DETECTED_CONTOURS" );
206 // Get selected polylines
207 QStringList aSelectedtPolylines = aPanel->getSelectedtPolylineNames();
208 // Remove the selected polylines from the panel
209 aPanel->removePolylineNames( aSelectedtPolylines );
212 foreach ( QString aName, aSelectedtPolylines ) {
213 TopoDS_Shape aShape = myPolylineShapes.value( aName )->getTopoShape();
214 if ( aShape.IsNull() ) {
218 Handle(HYDROData_PolylineXY) aPolylineObj =
219 Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
221 if( !aPolylineObj.IsNull() ) {
222 aPolylineObj->SetName( aName );
223 aPolylineObj->ImportShape( aShape );
224 aPolylineObj->SetWireColor( HYDROData_PolylineXY::DefaultWireColor() );
226 aPolylineObj->Update();
227 module()->setIsToUpdate( aPolylineObj );
230 // Remove the shape from the map
231 HYDROGUI_Shape* aShapeToDelete = myPolylineShapes.take( aName );
232 delete aShapeToDelete;
235 theUpdateFlags = UF_Model;
242 HYDROGUI_InputPanel* HYDROGUI_RecognizeContoursOp::createInputPanel() const
244 HYDROGUI_InputPanel* aPanel = new HYDROGUI_RecognizeContoursDlg( module(), getName() );
246 connect( aPanel, SIGNAL( selectionChanged( const QStringList& ) ), this, SLOT( onSelectionChanged( const QStringList& ) ) );
252 * Called when the operation perfomed by another module is finished.
253 * \param theModuleName the name of the module which perfomed the operation
254 * \param theOperationName the operation name
255 * \param theEntryList the list of the created objects entries
257 void HYDROGUI_RecognizeContoursOp::onExternalOperationFinished(
258 const QString& theModuleName, const QString& theOperationName,
259 const QStringList& theEntryList )
261 // Process "Geometry" module operations only
262 if ( theModuleName != "Geometry" ) {
266 // Store the operation name
267 myGEOMOpName = theOperationName;
269 // Close the dialog corresponding to the external operation
270 closeExternalOperationDlg();
272 // Erase the GEOM objects
273 LightApp_Displayer().Erase( theEntryList );
275 // Add GEOM object entries to the list of temporary GEOM objects
276 myTmpGeomObjects << theEntryList;
278 if ( theEntryList.count() == 1 ) {
279 myGeomContourEntry = theEntryList.first();
281 // Update the list of polylines
282 updateRecognizedPolylines();
287 Close the GEOM contours detection dialog.
289 void HYDROGUI_RecognizeContoursOp::closeExternalOperationDlg()
291 if ( myGEOMOpName.isEmpty() ) {
295 SUIT_Desktop* aDesktop = module()->getApp()->desktop();
297 QList<QDialog*> aDialogs = aDesktop->findChildren<QDialog*>();
298 foreach ( QDialog* aDlg, aDialogs ) {
299 if ( typeid(*aDlg).name() == myGEOMOpName ) {
308 Update the list of recognized polylines by exploding the GEOM contour object.
310 void HYDROGUI_RecognizeContoursOp::updateRecognizedPolylines()
316 SalomeApp_Study* aStudy =
317 dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
322 // Explode the compound
323 _PTR(SObject) aSObject( aStudy->studyDS()->FindObjectID( qPrintable( myGeomContourEntry ) ) );
325 TopoDS_Shape aShape = GEOMBase::GetShapeFromIOR( aSObject->GetIOR().c_str() );
327 TopTools_SequenceOfShape aSubShapes;
328 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_WIRE, aSubShapes );
329 if ( aSubShapes.Length() < 1 ) {
330 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_EDGE, aSubShapes );
333 Handle(AIS_InteractiveContext) aCtx = NULL;
336 if ( !getPreviewManager() ) {
337 setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>(
338 module()->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
341 OCCViewer_ViewManager* aViewManager = getPreviewManager();
342 if ( aViewManager ) {
343 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
344 // aViewer->enablePreselection( true );
345 // aViewer->enableSelection( true );
346 aCtx = aViewer->getAISContext();
347 connect( aViewer, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
351 QTransform aTrsf = myImage->Trsf();
352 gp_Mat aMat( aTrsf.m11(), aTrsf.m21(), 0,
353 aTrsf.m12(), -aTrsf.m22(), 0,
355 QImage anImage = myImage->Image();
356 QRectF aRect( QPointF( 0, 0 ), QPointF( anImage.width(), anImage.height() ) );
357 aRect = aTrsf.mapRect( aRect );
358 gp_XYZ aVec( aTrsf.m31() + aRect.width() * 0.5,
359 aTrsf.m32() - aRect.height() * 0.5, 0 );
361 BRepBuilderAPI_GTransform aBuilder( gp_GTrsf( aMat, aVec ) );
363 QStringList aNamesList;
364 for ( int i = 1; i <= aSubShapes.Length(); i++ ) {
365 TopoDS_Shape aSubShape = aSubShapes.Value( i );
367 // Transform the sub-shape
368 aBuilder.Perform( aSubShape, Standard_True );
369 if ( aBuilder.IsDone() ) {
370 aSubShape = aBuilder.Shape();
373 HYDROGUI_Shape* aShape = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
374 aShape->setShape( aSubShape, true, false );
375 aShape->setBorderColor( HYDROData_PolylineXY::DefaultWireColor(), false, false );
377 QString aPrefix = QString("%1_%2_%3").arg( myImage->GetName(), "Contour", QString::number( i ) );
378 QString aName = HYDROGUI_Tool::GenerateObjectName( module(), aPrefix, QStringList(), true );
379 myPolylineShapes.insert( aName, aShape);
383 if ( !aCtx.IsNull() ) {
384 aCtx->UpdateCurrentViewer();
388 HYDROGUI_RecognizeContoursDlg* aPanel =
389 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
391 aPanel->setPolylineNames( aNamesList );
399 void HYDROGUI_RecognizeContoursOp::erasePreview()
401 foreach ( HYDROGUI_Shape* aShape, myPolylineShapes ) {
405 myPolylineShapes.clear();
409 Called when selection of the recognized polylines is changed.
411 void HYDROGUI_RecognizeContoursOp::onSelectionChanged( const QStringList& theSelectedNames )
413 Handle(AIS_InteractiveContext) aCtx = NULL;
415 OCCViewer_ViewManager* aViewManager = getPreviewManager();
416 if ( aViewManager ) {
417 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
418 aCtx = aViewer->getAISContext();
422 if ( !aCtx.IsNull() ) {
423 foreach ( QString aName, myPolylineShapes.keys() ) {
424 Handle(AIS_InteractiveObject) anObject =
425 myPolylineShapes.value(aName)->getAISObject();
427 bool isSelected = theSelectedNames.contains( aName );
428 if ( ( isSelected && !aCtx->IsSelected( anObject) ) ||
429 ( !isSelected && aCtx->IsSelected( anObject) ) ) {
430 aCtx->AddOrRemoveSelected( anObject, Standard_False );
432 // myPolylineShapes[aName]->highlight( isSelected, true );
434 aCtx->UpdateCurrentViewer();
439 Called when selection in the viewer is changed.
441 void HYDROGUI_RecognizeContoursOp::onViewerSelectionChanged()
444 HYDROGUI_RecognizeContoursDlg* aPanel =
445 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
450 Handle(AIS_InteractiveContext) aCtx = NULL;
452 OCCViewer_ViewManager* aViewManager = getPreviewManager();
453 if ( aViewManager ) {
454 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
455 aCtx = aViewer->getAISContext();
459 if ( !aCtx.IsNull() ) {
460 QStringList aSelectedNames;
462 foreach ( QString aName, myPolylineShapes.keys() ) {
463 bool isSelected = aCtx->IsSelected( myPolylineShapes.value(aName)->getAISObject() );
465 aSelectedNames << aName;
469 aPanel->setSelectedPolylineNames( aSelectedNames );
474 Do the operation data cleanup.
476 void HYDROGUI_RecognizeContoursOp::cleanup()
478 // Close the external operation dialog
479 closeExternalOperationDlg();
484 // Delete temporary image file
485 if ( myTmpImageFile ) {
486 delete myTmpImageFile;
487 myTmpImageFile = NULL;
490 // Delete temporary GEOM objects
491 if ( !myTmpGeomObjects.isEmpty() ) {
492 HYDROGUI_Tool::DeleteGeomObjects( module(), myTmpGeomObjects );
493 // update the object browser
494 module()->getApp()->updateObjectBrowser( true );