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 SALOMEDS::Study_var aDSStudy = GeometryGUI::ClientStudyToStudy( aStudy->studyDS() );
131 GEOM::GEOM_Gen_var aGeomEngine = GeometryGUI::GetGeomGen();
133 QString aGeomPictureEntry;
135 HYDROData_GeomTool::createFaceInGEOM( aGeomEngine, aDSStudy, aQImage.width(), aQImage.height(),
136 anImageName, aGeomPictureEntry );
138 if ( !aGeomPictureEntry.isEmpty() ) {
139 aStudy->setObjectProperty( aViewMgr->getGlobalId(), aGeomPictureEntry,
140 GEOM::propertyName( GEOM::Texture ), myTmpImageFile->fileName() );
142 // update the object browser
143 module()->getApp()->updateObjectBrowser( true );
145 // browse the published GEOM picture
146 QStringList anEntries;
147 anEntries << aGeomPictureEntry;
148 browseObjects( anEntries );
150 // Add GEOM picture object entry to the list of temporary geom objects
151 myTmpGeomObjects << aGeomPictureEntry;
155 // Activate GEOM module operation
156 LightApp_Application* anApp = module()->getApp();
158 connect( anApp, SIGNAL( operationFinished( const QString&, const QString&, const QStringList& ) ),
159 this, SLOT( onExternalOperationFinished( const QString&, const QString&, const QStringList& ) ) );
161 module()->getApp()->activateOperation( "Geometry", GEOMOp::OpFeatureDetect );
167 void HYDROGUI_RecognizeContoursOp::abortOperation()
169 LightApp_Application* anApp = module()->getApp();
171 anApp->disconnect( this );
176 HYDROGUI_Operation::abortOperation();
181 void HYDROGUI_RecognizeContoursOp::commitOperation()
183 if ( isApplyAndClose() ) {
187 HYDROGUI_Operation::commitOperation();
192 bool HYDROGUI_RecognizeContoursOp::processApply( int& theUpdateFlags,
193 QString& theErrorMsg,
194 QStringList& theBrowseObjectsEntries )
196 // Check the original image
197 if ( myImage.IsNull() ) {
202 HYDROGUI_RecognizeContoursDlg* aPanel =
203 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
208 // Check if contour GEOM object exists
209 if ( myGeomContourEntry.isEmpty() ) {
210 theErrorMsg = tr( "NO_DETECTED_CONTOURS" );
214 // Get selected polylines
215 QStringList aSelectedtPolylines = aPanel->getSelectedtPolylineNames();
216 // Remove the selected polylines from the panel
217 aPanel->removePolylineNames( aSelectedtPolylines );
220 foreach ( QString aName, aSelectedtPolylines ) {
221 TopoDS_Shape aShape = myPolylineShapes.value( aName )->getTopoShape();
222 if ( aShape.IsNull() ) {
226 Handle(HYDROData_PolylineXY) aPolylineObj =
227 Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
229 if( !aPolylineObj.IsNull() ) {
230 aPolylineObj->SetName( aName );
231 aPolylineObj->ImportShape( aShape, false, NULL );
232 aPolylineObj->SetWireColor( HYDROData_PolylineXY::DefaultWireColor() );
234 aPolylineObj->Update();
235 module()->setIsToUpdate( aPolylineObj );
238 // Remove the shape from the map
239 HYDROGUI_Shape* aShapeToDelete = myPolylineShapes.take( aName );
240 delete aShapeToDelete;
243 theUpdateFlags = UF_Model;
250 HYDROGUI_InputPanel* HYDROGUI_RecognizeContoursOp::createInputPanel() const
252 HYDROGUI_InputPanel* aPanel = new HYDROGUI_RecognizeContoursDlg( module(), getName() );
254 connect( aPanel, SIGNAL( selectionChanged( const QStringList& ) ), this, SLOT( onSelectionChanged( const QStringList& ) ) );
260 * Called when the operation perfomed by another module is finished.
261 * \param theModuleName the name of the module which perfomed the operation
262 * \param theOperationName the operation name
263 * \param theEntryList the list of the created objects entries
265 void HYDROGUI_RecognizeContoursOp::onExternalOperationFinished(
266 const QString& theModuleName, const QString& theOperationName,
267 const QStringList& theEntryList )
269 // Process "Geometry" module operations only
270 if ( theModuleName != "Geometry" ) {
274 // Store the operation name
275 myGEOMOpName = theOperationName;
277 // Close the dialog corresponding to the external operation
278 closeExternalOperationDlg();
280 // Erase the GEOM objects
281 LightApp_Displayer().Erase( theEntryList );
283 // Add GEOM object entries to the list of temporary GEOM objects
284 myTmpGeomObjects << theEntryList;
286 if ( theEntryList.count() == 1 ) {
287 myGeomContourEntry = theEntryList.first();
289 // Update the list of polylines
290 updateRecognizedPolylines();
295 Close the GEOM contours detection dialog.
297 void HYDROGUI_RecognizeContoursOp::closeExternalOperationDlg()
299 if ( myGEOMOpName.isEmpty() ) {
303 SUIT_Desktop* aDesktop = module()->getApp()->desktop();
305 QList<QDialog*> aDialogs = aDesktop->findChildren<QDialog*>();
306 foreach ( QDialog* aDlg, aDialogs ) {
307 if ( typeid(*aDlg).name() == myGEOMOpName ) {
316 Update the list of recognized polylines by exploding the GEOM contour object.
318 void HYDROGUI_RecognizeContoursOp::updateRecognizedPolylines()
324 SalomeApp_Study* aStudy =
325 dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
330 // Explode the compound
331 _PTR(SObject) aSObject( aStudy->studyDS()->FindObjectID( qPrintable( myGeomContourEntry ) ) );
333 TopoDS_Shape aShape = GEOMBase::GetShapeFromIOR( aSObject->GetIOR().c_str() );
335 TopTools_SequenceOfShape aSubShapes;
336 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_WIRE, aSubShapes );
337 if ( aSubShapes.Length() < 1 ) {
338 HYDROData_ShapesTool::ExploreShapeToShapes( aShape, TopAbs_EDGE, aSubShapes );
341 Handle(AIS_InteractiveContext) aCtx = NULL;
344 OCCViewer_ViewManager* aViewManager = getPreviewManager();
345 if ( aViewManager ) {
346 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
347 // aViewer->enablePreselection( true );
348 // aViewer->enableSelection( true );
349 aCtx = aViewer->getAISContext();
350 connect( aViewer, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
354 QTransform aTrsf = myImage->Trsf();
355 QImage anImage = myImage->Image();
356 QRectF aRect( QPointF( 0, 0 ), QPointF( anImage.width(), anImage.height() ) );
357 aRect = aTrsf.mapRect( aRect );
358 aTrsf.setMatrix( aTrsf.m11(), aTrsf.m12(), aTrsf.m13(),
359 aTrsf.m21(), -aTrsf.m22(), aTrsf.m23(),
360 aTrsf.m31() + aRect.width() * 0.5, aTrsf.m32 () - aRect.height() * 0.5, aTrsf.m33() );
363 QTransform aTrsf = myImage->Trsf();
364 gp_Mat aMat( aTrsf.m11(), aTrsf.m21(), 0,
365 aTrsf.m12(), -aTrsf.m22(), 0,
367 QImage anImage = myImage->Image();
368 QRectF aRect( QPointF( 0, 0 ), QPointF( anImage.width(), anImage.height() ) );
369 aRect = aTrsf.mapRect( aRect );
370 gp_XYZ aVec( aTrsf.m31() + aRect.width() * 0.5,
371 aTrsf.m32() - aRect.height() * 0.5, 0 );
373 BRepBuilderAPI_GTransform aBuilder( gp_GTrsf( aMat, aVec ) );
376 Handle(HYDROData_PolylineXY) aPolylineObj = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
377 QStringList aNamesList;
378 for ( int i = 1; i <= aSubShapes.Length(); i++ ) {
379 TopoDS_Shape aSubShape = aSubShapes.Value( i );
381 // Transform the sub-shape
382 aPolylineObj->ImportShape( aSubShape, false, NULL );
383 aPolylineObj->Transform( aTrsf );
386 aBuilder.Perform( aSubShape, Standard_True );
387 if ( aBuilder.IsDone() ) {
388 aSubShape = aBuilder.Shape();
391 HYDROGUI_Shape* aShape = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
392 aShape->setShape( aPolylineObj->GetShape(), true, false );
393 aShape->setBorderColor( HYDROData_PolylineXY::DefaultWireColor(), false, false );
395 QString aPrefix = QString("%1_%2_%3").arg( myImage->GetName(), "Contour", QString::number( i ) );
396 QString aName = HYDROGUI_Tool::GenerateObjectName( module(), aPrefix, QStringList(), true );
397 myPolylineShapes.insert( aName, aShape);
401 aPolylineObj->Remove();
403 if ( !aCtx.IsNull() ) {
404 UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, Graphic3d_ZLayerId_TopOSD );
405 aCtx->UpdateCurrentViewer();
409 HYDROGUI_RecognizeContoursDlg* aPanel =
410 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
412 aPanel->setPolylineNames( aNamesList );
420 void HYDROGUI_RecognizeContoursOp::erasePreview()
422 foreach ( HYDROGUI_Shape* aShape, myPolylineShapes ) {
426 myPolylineShapes.clear();
430 Called when selection of the recognized polylines is changed.
432 void HYDROGUI_RecognizeContoursOp::onSelectionChanged( const QStringList& theSelectedNames )
434 Handle(AIS_InteractiveContext) aCtx = NULL;
436 OCCViewer_ViewManager* aViewManager = getPreviewManager();
437 if ( aViewManager ) {
438 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
439 aCtx = aViewer->getAISContext();
443 if ( !aCtx.IsNull() ) {
444 foreach ( QString aName, myPolylineShapes.keys() ) {
445 Handle(AIS_InteractiveObject) anObject =
446 myPolylineShapes.value(aName)->getAISObjects()[0];
448 bool isSelected = theSelectedNames.contains( aName );
449 if ( ( isSelected && !aCtx->IsSelected( anObject) ) ||
450 ( !isSelected && aCtx->IsSelected( anObject) ) ) {
451 aCtx->AddOrRemoveSelected( anObject, Standard_False );
453 // myPolylineShapes[aName]->highlight( isSelected, true );
455 aCtx->UpdateCurrentViewer();
460 Called when selection in the viewer is changed.
462 void HYDROGUI_RecognizeContoursOp::onViewerSelectionChanged()
465 HYDROGUI_RecognizeContoursDlg* aPanel =
466 ::qobject_cast<HYDROGUI_RecognizeContoursDlg*>( inputPanel() );
472 OCCViewer_ViewManager* aViewManager = getPreviewManager();
473 Handle(AIS_InteractiveContext) aCtx = NULL;
474 if ( aViewManager ) {
475 if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
476 aCtx = aViewer->getAISContext();
480 if ( !aCtx.IsNull() ) {
481 QStringList aSelectedNames;
483 foreach ( QString aName, myPolylineShapes.keys() ) {
484 bool isSelected = aCtx->IsSelected( myPolylineShapes.value(aName)->getAISObjects()[0] );
486 aSelectedNames << aName;
490 aPanel->setSelectedPolylineNames( aSelectedNames );
495 Do the operation data cleanup.
497 void HYDROGUI_RecognizeContoursOp::cleanup()
499 // Close the external operation dialog
500 closeExternalOperationDlg();
505 // Delete temporary image file
506 if ( myTmpImageFile ) {
507 delete myTmpImageFile;
508 myTmpImageFile = NULL;
511 // Delete temporary GEOM objects
512 if ( !myTmpGeomObjects.isEmpty() ) {
513 HYDROGUI_Tool::DeleteGeomObjects( module(), myTmpGeomObjects );
514 // update the object browser
515 module()->getApp()->updateObjectBrowser( true );