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"
27 #include "HYDROGUI_ZLayers.h" //@MZN
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>
56 #include <QTemporaryFile>
61 HYDROGUI_RecognizeContoursOp::HYDROGUI_RecognizeContoursOp( HYDROGUI_Module* theModule )
62 : HYDROGUI_Operation( theModule ),
65 setName( tr( "CONTOURS_RECOGNITION" ) );
71 HYDROGUI_RecognizeContoursOp::~HYDROGUI_RecognizeContoursOp()
78 void HYDROGUI_RecognizeContoursOp::startOperation()
80 HYDROGUI_Operation::startOperation();
82 if ( !isApplyAndClose() ) {
86 // Get the selected image
87 myImage = Handle(HYDROData_Image)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
88 if ( myImage.IsNull() ) {
92 QString anImageName = myImage->GetName();
94 // Create temporary graphics file
95 QImage aQImage = myImage->Image();
96 myTmpImageFile = new QTemporaryFile( anImageName );
97 if ( !myTmpImageFile->open() ||
98 !aQImage.save( myTmpImageFile->fileName(), "PNG", 100 ) ) {
103 // Create the input panel
104 HYDROGUI_RecognizeContoursDlg* aPanel =
105 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
112 aPanel->setImageName( anImageName );
115 SalomeApp_Study* aStudy =
116 dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
118 // Get active view manager
119 SUIT_ViewManager* aViewMgr = module()->getApp()->activeViewManager();
121 // Export the selected image to GEOM module
122 if ( aStudy && aViewMgr ) {
123 SALOMEDS::Study_var aDSStudy = GeometryGUI::ClientStudyToStudy( aStudy->studyDS() );
124 GEOM::GEOM_Gen_var aGeomEngine = GeometryGUI::GetGeomGen();
126 QString aGeomPictureEntry;
128 HYDROData_GeomTool::createFaceInGEOM( aGeomEngine, aDSStudy, aQImage.width(), aQImage.height(),
129 anImageName, aGeomPictureEntry );
131 if ( !aGeomPictureEntry.isEmpty() ) {
132 aStudy->setObjectProperty( aViewMgr->getGlobalId(), aGeomPictureEntry,
133 GEOM::propertyName( GEOM::Texture ), myTmpImageFile->fileName() );
135 // update the object browser
136 module()->getApp()->updateObjectBrowser( true );
138 // select the picture
139 SUIT_DataOwnerPtrList aList( true );
140 aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aGeomPictureEntry ) ) );
141 selectionMgr()->setSelected(aList );
143 // Add GEOM picture object entry to the list of temporary geom objects
144 myTmpGeomObjects << aGeomPictureEntry;
148 // Activate GEOM module operation
149 LightApp_Application* anApp = module()->getApp();
151 connect( anApp, SIGNAL( operationFinished( const QString&, const QString&, const QStringList& ) ),
152 this, SLOT( onExternalOperationFinished( const QString&, const QString&, const QStringList& ) ) );
154 module()->getApp()->activateOperation( "Geometry", GEOMOp::OpFeatureDetect );
160 void HYDROGUI_RecognizeContoursOp::abortOperation()
162 LightApp_Application* anApp = module()->getApp();
164 anApp->disconnect( this );
169 HYDROGUI_Operation::abortOperation();
174 void HYDROGUI_RecognizeContoursOp::commitOperation()
176 if ( isApplyAndClose() ) {
180 HYDROGUI_Operation::commitOperation();
185 bool HYDROGUI_RecognizeContoursOp::processApply( int& theUpdateFlags,
186 QString& theErrorMsg,
187 QStringList& theBrowseObjectsEntries )
189 // Check the original image
190 if ( myImage.IsNull() ) {
195 HYDROGUI_RecognizeContoursDlg* aPanel =
196 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
201 // Check if contour GEOM object exists
202 if ( myGeomContourEntry.isEmpty() ) {
203 theErrorMsg = tr( "NO_DETECTED_CONTOURS" );
207 // Get selected polylines
208 QStringList aSelectedtPolylines = aPanel->getSelectedtPolylineNames();
209 // Remove the selected polylines from the panel
210 aPanel->removePolylineNames( aSelectedtPolylines );
213 foreach ( QString aName, aSelectedtPolylines ) {
214 TopoDS_Shape aShape = myPolylineShapes.value( aName )->getTopoShape();
215 if ( aShape.IsNull() ) {
219 Handle(HYDROData_PolylineXY) aPolylineObj =
220 Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
222 if( !aPolylineObj.IsNull() ) {
223 aPolylineObj->SetName( aName );
224 aPolylineObj->ImportShape( aShape );
225 aPolylineObj->SetWireColor( HYDROData_PolylineXY::DefaultWireColor() );
227 aPolylineObj->Update();
228 module()->setIsToUpdate( aPolylineObj );
231 // Remove the shape from the map
232 HYDROGUI_Shape* aShapeToDelete = myPolylineShapes.take( aName );
233 delete aShapeToDelete;
236 theUpdateFlags = UF_Model;
243 HYDROGUI_InputPanel* HYDROGUI_RecognizeContoursOp::createInputPanel() const
245 HYDROGUI_InputPanel* aPanel = new HYDROGUI_RecognizeContoursDlg( module(), getName() );
247 connect( aPanel, SIGNAL( selectionChanged( const QStringList& ) ), this, SLOT( onSelectionChanged( const QStringList& ) ) );
253 * Called when the operation perfomed by another module is finished.
254 * \param theModuleName the name of the module which perfomed the operation
255 * \param theOperationName the operation name
256 * \param theEntryList the list of the created objects entries
258 void HYDROGUI_RecognizeContoursOp::onExternalOperationFinished(
259 const QString& theModuleName, const QString& theOperationName,
260 const QStringList& theEntryList )
262 // Process "Geometry" module operations only
263 if ( theModuleName != "Geometry" ) {
267 // Store the operation name
268 myGEOMOpName = theOperationName;
270 // Close the dialog corresponding to the external operation
271 closeExternalOperationDlg();
273 // Erase the GEOM objects
274 LightApp_Displayer().Erase( theEntryList );
276 // Add GEOM object entries to the list of temporary GEOM objects
277 myTmpGeomObjects << theEntryList;
279 if ( theEntryList.count() == 1 ) {
280 myGeomContourEntry = theEntryList.first();
282 // Update the list of polylines
283 updateRecognizedPolylines();
288 Close the GEOM contours detection dialog.
290 void HYDROGUI_RecognizeContoursOp::closeExternalOperationDlg()
292 if ( myGEOMOpName.isEmpty() ) {
296 SUIT_Desktop* aDesktop = module()->getApp()->desktop();
298 QList<QDialog*> aDialogs = aDesktop->findChildren<QDialog*>();
299 foreach ( QDialog* aDlg, aDialogs ) {
300 if ( typeid(*aDlg).name() == myGEOMOpName ) {
309 Update the list of recognized polylines by exploding the GEOM contour object.
311 void HYDROGUI_RecognizeContoursOp::updateRecognizedPolylines()
317 SalomeApp_Study* aStudy =
318 dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
323 // Explode the compound
324 _PTR(SObject) aSObject( aStudy->studyDS()->FindObjectID( qPrintable( myGeomContourEntry ) ) );
326 TopoDS_Shape aShape = GEOMBase::GetShapeFromIOR( aSObject->GetIOR().c_str() );
328 TopTools_SequenceOfShape aSubShapes;
329 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_WIRE, aSubShapes );
330 if ( aSubShapes.Length() < 1 ) {
331 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_EDGE, aSubShapes );
334 Handle(AIS_InteractiveContext) aCtx = NULL;
337 if ( !getPreviewManager() ) {
338 setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>(
339 module()->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
342 OCCViewer_ViewManager* aViewManager = getPreviewManager();
343 if ( aViewManager ) {
344 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
345 // aViewer->enablePreselection( true );
346 // aViewer->enableSelection( true );
347 aCtx = aViewer->getAISContext();
348 connect( aViewer, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
352 QTransform aTrsf = myImage->Trsf();
353 QImage anImage = myImage->Image();
354 QRectF aRect( QPointF( 0, 0 ), QPointF( anImage.width(), anImage.height() ) );
355 aRect = aTrsf.mapRect( aRect );
356 aTrsf.setMatrix( aTrsf.m11(), aTrsf.m12(), aTrsf.m13(),
357 aTrsf.m21(), -aTrsf.m22(), aTrsf.m23(),
358 aTrsf.m31() + aRect.width() * 0.5, aTrsf.m32 () - aRect.height() * 0.5, aTrsf.m33() );
361 QTransform aTrsf = myImage->Trsf();
362 gp_Mat aMat( aTrsf.m11(), aTrsf.m21(), 0,
363 aTrsf.m12(), -aTrsf.m22(), 0,
365 QImage anImage = myImage->Image();
366 QRectF aRect( QPointF( 0, 0 ), QPointF( anImage.width(), anImage.height() ) );
367 aRect = aTrsf.mapRect( aRect );
368 gp_XYZ aVec( aTrsf.m31() + aRect.width() * 0.5,
369 aTrsf.m32() - aRect.height() * 0.5, 0 );
371 BRepBuilderAPI_GTransform aBuilder( gp_GTrsf( aMat, aVec ) );
374 Handle(HYDROData_PolylineXY) aPolylineObj = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
375 QStringList aNamesList;
376 for ( int i = 1; i <= aSubShapes.Length(); i++ ) {
377 TopoDS_Shape aSubShape = aSubShapes.Value( i );
379 // Transform the sub-shape
380 aPolylineObj->ImportShape( aSubShape );
381 aPolylineObj->Transform( aTrsf );
384 aBuilder.Perform( aSubShape, Standard_True );
385 if ( aBuilder.IsDone() ) {
386 aSubShape = aBuilder.Shape();
389 HYDROGUI_Shape* aShape = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
390 aShape->setShape( aPolylineObj->GetShape(), true, false );
391 aShape->setBorderColor( HYDROData_PolylineXY::DefaultWireColor(), false, false );
393 QString aPrefix = QString("%1_%2_%3").arg( myImage->GetName(), "Contour", QString::number( i ) );
394 QString aName = HYDROGUI_Tool::GenerateObjectName( module(), aPrefix, QStringList(), true );
395 myPolylineShapes.insert( aName, aShape);
399 aPolylineObj->Remove();
401 if ( !aCtx.IsNull() ) {
402 UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, Graphic3d_ZLayerId_TopOSD );
403 aCtx->UpdateCurrentViewer();
407 HYDROGUI_RecognizeContoursDlg* aPanel =
408 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
410 aPanel->setPolylineNames( aNamesList );
418 void HYDROGUI_RecognizeContoursOp::erasePreview()
420 foreach ( HYDROGUI_Shape* aShape, myPolylineShapes ) {
424 myPolylineShapes.clear();
428 Called when selection of the recognized polylines is changed.
430 void HYDROGUI_RecognizeContoursOp::onSelectionChanged( const QStringList& theSelectedNames )
432 Handle(AIS_InteractiveContext) aCtx = NULL;
434 OCCViewer_ViewManager* aViewManager = getPreviewManager();
435 if ( aViewManager ) {
436 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
437 aCtx = aViewer->getAISContext();
441 if ( !aCtx.IsNull() ) {
442 foreach ( QString aName, myPolylineShapes.keys() ) {
443 Handle(AIS_InteractiveObject) anObject =
444 myPolylineShapes.value(aName)->getAISObject();
446 bool isSelected = theSelectedNames.contains( aName );
447 if ( ( isSelected && !aCtx->IsSelected( anObject) ) ||
448 ( !isSelected && aCtx->IsSelected( anObject) ) ) {
449 aCtx->AddOrRemoveSelected( anObject, Standard_False );
451 // myPolylineShapes[aName]->highlight( isSelected, true );
453 aCtx->UpdateCurrentViewer();
458 Called when selection in the viewer is changed.
460 void HYDROGUI_RecognizeContoursOp::onViewerSelectionChanged()
463 HYDROGUI_RecognizeContoursDlg* aPanel =
464 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
469 Handle(AIS_InteractiveContext) aCtx = NULL;
471 OCCViewer_ViewManager* aViewManager = getPreviewManager();
472 if ( aViewManager ) {
473 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
474 aCtx = aViewer->getAISContext();
478 if ( !aCtx.IsNull() ) {
479 QStringList aSelectedNames;
481 foreach ( QString aName, myPolylineShapes.keys() ) {
482 bool isSelected = aCtx->IsSelected( myPolylineShapes.value(aName)->getAISObject() );
484 aSelectedNames << aName;
488 aPanel->setSelectedPolylineNames( aSelectedNames );
493 Do the operation data cleanup.
495 void HYDROGUI_RecognizeContoursOp::cleanup()
497 // Close the external operation dialog
498 closeExternalOperationDlg();
503 // Delete temporary image file
504 if ( myTmpImageFile ) {
505 delete myTmpImageFile;
506 myTmpImageFile = NULL;
509 // Delete temporary GEOM objects
510 if ( !myTmpGeomObjects.isEmpty() ) {
511 HYDROGUI_Tool::DeleteGeomObjects( module(), myTmpGeomObjects );
512 // update the object browser
513 module()->getApp()->updateObjectBrowser( true );