1 // Copyright (C) 2007-2020 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, or (at your option) any later version.
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
22 // File : SMESHGUI_MG_ADAPTDRIVER.cxx
24 #include "SMESHGUI_MG_ADAPTDRIVER.h"
26 #include "SUIT_Desktop.h"
27 #include "SUIT_Application.h"
28 #include "SUIT_Session.h"
30 #include "SalomeApp_Application.h"
31 #include "SalomeApp_Module.h"
32 #include "SalomeApp_Study.h"
34 #include "SMESH_Comment.hxx"
35 #include "SMESH_Actor.h"
37 #include "SMESHGUI_FilterDlg.h"
38 #include "SMESHGUI_Selection.h"
39 #include <SUIT_MessageBox.h>
40 #include "SMESHGUI_IdValidator.h"
41 #include "SMESHGUI_Utils.h"
42 #include "SMESHGUI_MeshEditPreview.h"
43 #include "SMESHGUI_VTKUtils.h"
44 #include <SMESH_TypeFilter.hxx>
45 #include <SMESH_MeshAlgos.hxx>
46 #include <SMESH_LogicalFilter.hxx>
47 #include <SMDS_Mesh.hxx>
48 #include <SMDS_MeshNode.hxx>
49 #include "SMESHGUI_SpinBox.h"
51 #include <LightApp_SelectionMgr.h>
52 #include <SUIT_OverrideCursor.h>
53 #include <SUIT_ResourceMgr.h>
54 #include <SVTK_ViewWindow.h>
55 #include <SALOME_ListIO.hxx>
56 #include <SUIT_FileDlg.h>
57 #include "SMESHGUI_MeshUtils.h"
60 #include <QApplication>
61 #include <QButtonGroup>
62 #include <QGridLayout>
64 #include <QHBoxLayout>
69 #include <QPushButton>
70 #include <QRadioButton>
72 #include <QVBoxLayout>
73 #include <QDoubleSpinBox>
75 #include <QTreeWidget>
76 #include <QTreeWidgetItem>
77 #include <QSpacerItem>
79 #include <QHeaderView>
80 #include <QItemDelegate>
81 #include <QFileDialog>
82 #include <QMessageBox>
85 #include <vtkPoints.h>
86 #include <vtkUnstructuredGrid.h>
87 #include <vtkIdList.h>
88 #include <vtkCellArray.h>
89 #include <vtkUnsignedCharArray.h>
90 #include <vtkDataSetMapper.h>
91 #include <VTKViewer_CellLocationsArray.h>
92 #include <vtkProperty.h>
95 // SALOME KERNEL includes
96 #include <SALOMEDS_SComponent.hxx>
97 #include <SALOMEDS_SObject.hxx>
98 #include <SALOMEDS_Study.hxx>
99 #include <SALOMEDS_wrap.hxx>
100 #include "SalomeApp_Tools.h"
101 #include <SALOMEconfig.h>
103 #include <utilities.h>
105 #include <TCollection_AsciiString.hxx>
107 const int SPACING = 6; // layout spacing
108 const int MARGIN = 9; // layout margin
110 SALOME_ListIO mySelected;
113 //================================================================
114 // Function : firstIObject
115 // Purpose : Return the first selected object in the selected object list
116 //================================================================
117 Handle(SALOME_InteractiveObject) firstIObject()
119 const SALOME_ListIO& aList = selectedIO();
120 return aList.Extent() > 0 ? aList.First() : Handle(SALOME_InteractiveObject)();
122 //================================================================
123 // Function : selectedIO
124 // Return the list of selected SALOME_InteractiveObject's
125 //================================================================
126 const SALOME_ListIO& selectedIO()
128 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* > ( SUIT_Session::session()->activeApplication() );
129 LightApp_SelectionMgr* aSelectionMgr = app->selectionMgr();
132 aSelectionMgr->selectedObjects( mySelected );
133 for (SALOME_ListIteratorOfListIO it (mySelected); it.More(); it.Next())
134 SCRUTE(it.Value()->getEntry());
138 //================================================================
139 // Function : getStudy
140 // Returne un pointeur sur l'etude active
141 //================================================================
142 _PTR(Study) getStudy()
144 static _PTR(Study) _study;
146 _study = SalomeApp_Application::getStudy();
150 bool createAndPublishMed(QString fileName)
153 SMESH::DriverMED_ReadStatus res;
154 SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
157 aMeshes = SMESHGUI::GetSMESHGen()->CreateMeshesFromMED( fileName.toUtf8().constData(), res );
158 _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[0] );
159 _PTR(Study) aStudy = SMESH::getStudy();
160 QStringList anEntryList;
163 _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
164 _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
165 aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
166 anEntryList.append( aMeshSO->GetID().c_str() );
172 SMESHGUI::GetSMESHGUI()->updateObjBrowser();
174 // browse to the published meshes
175 if( LightApp_Application* anApp =
176 dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
177 anApp->browseObjects( anEntryList );
180 bool createMgAdaptObject(MgAdapt *myMgAdapt )
182 // SMESH::SMESH_Mesh_var newMesh = SMESHGUI::GetSMESHGen()->CreateEmptyMesh();
184 // _PTR(SObject) aHypothesis;
185 _PTR(Study) aStudy = SMESH::getStudy();
186 QStringList anEntryList;
187 _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
188 _PTR(SComponent) mgadapt = aStudy->FindComponent("MG-ADAPT");
189 _PTR(GenericAttribute) ga;
190 if (!aBuilder->FindAttribute(mgadapt, ga, "AttributeName") )
192 mgadapt = aBuilder->NewComponent("MG-ADAPT");
193 _PTR(AttributeName) Name = aBuilder->FindOrCreateAttribute(mgadapt, "AttributeName");
194 Name->SetValue("MG-ADAPT");
195 _PTR(AttributePixMap) myPixmap = aBuilder->FindOrCreateAttribute( mgadapt, "AttributePixMap" );
196 myPixmap->SetPixMap( "ICON_MG_ADAPT" );
197 anEntryList.append( mgadapt->GetID().c_str() );
200 _PTR(SObject) obj = aBuilder->NewObject(mgadapt);
201 _PTR(AttributeName) myName = aBuilder->FindOrCreateAttribute(obj, "AttributeName");
202 myName->SetValue("hypo");
203 _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( obj, "AttributePixMap" );
204 aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO" );
205 anEntryList.append( obj->GetID().c_str() );
207 SMESHGUI::GetSMESHGUI()->updateObjBrowser();
209 // // browse to the published meshes
210 if( LightApp_Application* anApp =
211 dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
212 anApp->browseObjects( anEntryList );
218 //================================================================
219 // Function : IObjectCount
220 // Return the number of selected objects
221 //================================================================
224 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
225 LightApp_SelectionMgr* aSelectionMgr = app->selectionMgr();
228 aSelectionMgr->selectedObjects( mySelected );
229 SCRUTE(mySelected.Extent());
230 return mySelected.Extent();
236 SMESHGUI_MG_AdaptComputeDlg_QThread::SMESHGUI_MG_AdaptComputeDlg_QThread(MgAdapt* aModel)
242 void SMESHGUI_MG_AdaptComputeDlg_QThread::run()
247 errStr = model->compute(errStr);
248 std::string msg = err == 0 ? " ok" : std::string("Not ok \n")+ errStr;
252 int SMESHGUI_MG_AdaptComputeDlg_QThread::result()
257 void SMESHGUI_MG_AdaptComputeDlg_QThread::cancel()
262 SMESHGUI_MG_ADAPTDRIVER::SMESHGUI_MG_ADAPTDRIVER( SMESHGUI* theModule, MgAdapt* myModel, bool isCreation )
263 : mySMESHGUI( theModule ),
265 myIsApplyAndClose( false ),
266 SMESHGUI_MgAdaptDlg((SalomeApp_Module*)theModule, myModel, SMESHGUI::desktop(), isCreation)
269 resMgr = resourceMgr();
271 selMgr = selectionMgr();
274 connect(myArgs, SIGNAL(updateSelection()), this, SLOT(updateSelection()));
275 connect(myArgs, SIGNAL(toExportMED(const char*)), this, SLOT(exportMED(const char*)));
278 SUIT_ResourceMgr* SMESHGUI_MG_ADAPTDRIVER::resourceMgr()
280 return dynamic_cast<SUIT_ResourceMgr*>( SUIT_Session::session()->resourceMgr() );
283 LightApp_SelectionMgr* SMESHGUI_MG_ADAPTDRIVER::selectionMgr()
285 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
287 return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
292 void SMESHGUI_MG_ADAPTDRIVER::updateSelection()
294 disconnect( selMgr, 0, this, 0 );
295 selMgr->clearFilters();
297 SMESH::SetPointRepresentation( true );
298 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
299 aViewWindow->SetSelectionMode( ActorSelection );
300 if (myArgs->aBrowser->isChecked())
302 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ));
307 void SMESHGUI_MG_ADAPTDRIVER::selectionChanged()
309 //~ get selected mesh
311 selMgr->selectedObjects(aList);
312 QString aString = "";
313 int nbSel = aList.Extent();
317 Handle(SALOME_InteractiveObject) IO = aList.First();
318 SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(IO);
319 if ( !mesh->_is_nil() )
323 mySelectedObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
324 if ( mySelectedObject->_is_nil() )
331 SMESH::GetNameOfSelectedIObjects( selMgr, aString );
332 if ( aString.isEmpty() ) aString = " ";
333 else aString = aString.trimmed();
336 bool ok = !aString.isEmpty();
337 if ( !mesh->_is_nil() )
339 myArgs->aBrowserObject->setText( aString );
340 myArgs->meshNameLineEdit->setText( aString );
341 myArgs->selectOutMedFileLineEdit->setText(aString+QString(".med"));
342 ADAPTATION_MODE aMode;
343 int nbVolumes = myMesh->NbVolumes();
344 int nbFaces = myMesh->NbFaces();
345 if(nbFaces > 0 && nbVolumes > 0) aMode = ADAPTATION_MODE::BOTH;
346 else if(nbFaces > 0) aMode = ADAPTATION_MODE::SURFACE;
347 else aMode = ADAPTATION_MODE::VOLUME;
348 emit myArgs->meshDimSignal(aMode);
352 void SMESHGUI_MG_ADAPTDRIVER::exportMED(const char* tmp_file)
354 bool toOverwrite = true;
355 bool toFindOutDim = true;
356 myMesh->ExportMED(tmp_file, false, -1, toOverwrite, toFindOutDim);
358 void SMESHGUI_MG_ADAPTDRIVER::setMyMesh(SMESH::SMESH_Mesh_var mesh)
362 SMESH::SMESH_Mesh_var SMESHGUI_MG_ADAPTDRIVER::getMyMesh()
367 //=================================================================================
368 // function : ClickOnOk()
370 //=================================================================================
371 void SMESHGUI_MG_ADAPTDRIVER::clickOnOk()
373 setIsApplyAndClose( true );
377 bool SMESHGUI_MG_ADAPTDRIVER::clickOnApply()
380 if ( SMESHGUI::isStudyLocked() )
385 SMESHGUI_MgAdaptDlg::clickOnApply();
388 //~SMESHGUI_MG_AdaptComputeDlg_QThread atest(getModel());
391 if (getModel()->getPublish()) this->createMeshInObjectBrowser();
396 bool SMESHGUI_MG_ADAPTDRIVER::execute()
403 err = getModel()->compute(errStr);
404 std::string msg = err == 0 ? " ok" : std::string("Not ok \n")+errStr ;
406 catch (const std::exception& e)
410 return err == 0? true: false;
413 //=================================================================================
416 //=================================================================================
417 void SMESHGUI_MG_ADAPTDRIVER::Init (bool ResetControls)
423 myLineEditElements->clear();
426 buttonOk->setEnabled(false);
427 buttonApply->setEnabled(false);
430 myMesh = SMESH::SMESH_Mesh::_nil();
432 myIdSourceCheck->setChecked(true);
439 //=======================================================================
440 //function : onConstructor
441 //purpose : switch operation mode
442 //=======================================================================
444 void SMESHGUI_MG_ADAPTDRIVER::onConstructor( int withGeom )
447 myGeomLabel ->setVisible( withGeom );
448 myGeomNameEdit ->setVisible( withGeom );
449 myReuseHypCheck ->setVisible( withGeom );
450 myCopyElementsCheck->setVisible( withGeom );
451 myFilterBtn ->setVisible( !withGeom );
452 myIdSourceCheck ->setVisible( !withGeom );
455 myMeshNameEdit->setText( SMESH::UniqueMeshName("Mesh"));
460 //~void SMESHGUI_MG_ADAPTDRIVER::onSelectIdSource( bool )
464 //=================================================================================
465 // function : enterEvent()
467 //=================================================================================
468 void SMESHGUI_MG_ADAPTDRIVER::enterEvent (QEvent*)
471 // if ( !ConstructorsBox->isEnabled() ) {
472 // SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
473 // if ( aViewWindow && !mySelector ) {
474 // mySelector = aViewWindow->GetSelector();
476 // activateThisDialog();
481 //=================================================================================
482 // function : keyPressEvent()
484 //=================================================================================
485 void SMESHGUI_MG_ADAPTDRIVER::keyPressEvent( QKeyEvent* e )
488 QDialog::keyPressEvent( e );
489 if ( e->isAccepted() )
492 if ( e->key() == Qt::Key_F1 ) {
499 //=================================================================================
500 // function : clickOnHelp()
502 //=================================================================================
503 void SMESHGUI_MG_ADAPTDRIVER::clickOnHelp()
506 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
508 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
512 platform = "winapplication";
514 platform = "application";
516 SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
517 tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
518 arg(app->resourceMgr()->stringValue("ExternalBrowser",
520 arg(myHelpFileName));
525 //=======================================================================
526 //function : getErrorMsg
527 //purpose : Return an error message and entries of invalid smesh object
528 //=======================================================================
530 QString SMESHGUI_MG_ADAPTDRIVER::getErrorMsg( SMESH::string_array_var theInvalidEntries,
531 QStringList & theEntriesToBrowse )
534 if ( theInvalidEntries->length() == 0 )
535 return tr("OPERATION_FAILED");
537 // theInvalidEntries - SObject's that hold geometry objects whose
538 // counterparts are not found in the newGeometry, followed by SObject's
539 // holding mesh sub-objects that are invalid because they depend on a not found
540 // preceding sub-shape
542 QString msg = tr("SUBSHAPES_NOT_FOUND_MSG") + "\n";
545 for ( CORBA::ULong i = 0; i < theInvalidEntries->length(); ++i )
547 _PTR(SObject) so = SMESH::getStudy()->FindObjectID( theInvalidEntries[i].in() );
549 int objType = SMESHGUI_Selection::type( theInvalidEntries[i].in() );
550 if ( objType < 0 ) // geom object
554 objString += so->GetName().c_str();
556 objString += theInvalidEntries[i].in(); // it's something like "FACE #2"
560 theEntriesToBrowse.push_back( theInvalidEntries[i].in() );
565 objString += tr("SMESH_MESH");
567 case SMESH::HYPOTHESIS:
568 objString += tr("SMESH_HYPOTHESIS");
570 case SMESH::ALGORITHM:
571 objString += tr("SMESH_ALGORITHM");
573 case SMESH::SUBMESH_VERTEX:
574 case SMESH::SUBMESH_EDGE:
575 case SMESH::SUBMESH_FACE:
576 case SMESH::SUBMESH_SOLID:
577 case SMESH::SUBMESH_COMPOUND:
579 objString += tr("SMESH_SUBMESH");
582 objString += tr("SMESH_GROUP");
589 objString += so->GetName().c_str();
591 objString += theInvalidEntries[i].in();
595 if ( !objString.isEmpty() )
601 //=================================================================================
602 // function : isValid
604 //=================================================================================
606 bool SMESHGUI_MG_ADAPTDRIVER::isValid()
612 bool SMESHGUI_MG_ADAPTDRIVER::createMeshInObjectBrowser()
614 QString filename(getModel()->getMedFileOut().c_str());
616 QStringList anEntryList;
617 bool isEmpty = false;
619 SMESH::SMESH_Gen_var SMESH_Gen_ptr = SMESHGUI::GetSMESHGen();
620 if (!SMESH_Gen_ptr) {
621 std::cerr << "Could not retrieve SMESH_Gen_ptr" << std::endl;
622 throw SALOME_Exception(LOCALIZED("Could not retrieve SMESH::GetSMESHGen()"));
624 SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
625 aMeshes->length( 1 ); // one mesh only
626 SMESH::DriverMED_ReadStatus res;
627 aMeshes = SMESH_Gen_ptr->CreateMeshesFromMED( filename.toUtf8().constData(), res );
628 if ( res != SMESH::DRS_OK ) {
629 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
631 _PTR(Study) aStudy = SMESH::getStudy();
632 for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ )
634 _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] );
636 _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
637 _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
638 aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); // put REFINED mesh ico
639 anEntryList.append( aMeshSO->GetID().c_str() );
645 // update Object browser
646 SMESHGUI::GetSMESHGUI()->updateObjBrowser();
647 // browse to the published meshes
648 if( LightApp_Application* anApp =
649 dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
650 anApp->browseObjects( anEntryList );
652 // show Error message box if there were errors
653 if ( errors.count() > 0 ) {
654 SUIT_MessageBox::critical( SMESHGUI::desktop(),
655 QObject::tr( "SMESH_ERROR" ),
656 QObject::tr( "SMESH_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) );
659 // show warning message box, if some imported mesh is empty
661 SUIT_MessageBox::warning( SMESHGUI::desktop(),
662 QObject::tr( "SMESH_WRN_WARNING" ),
663 QObject::tr( "SMESH_DRS_SOME_EMPTY" ) );
668 //================================================================
669 // function : setIsApplyAndClose
670 // Purpose : Set value of the flag indicating that the dialog is
671 // accepted by Apply & Close button
672 //================================================================
673 void SMESHGUI_MG_ADAPTDRIVER::setIsApplyAndClose( const bool theFlag )
675 myIsApplyAndClose = theFlag;
676 }//================================================================
677 // function : isApplyAndClose
678 // Purpose : Get value of the flag indicating that the dialog is
679 // accepted by Apply & Close button
680 //================================================================
681 bool SMESHGUI_MG_ADAPTDRIVER::isApplyAndClose() const
683 return myIsApplyAndClose;
686 //=================================================================================
687 // function : DeactivateActiveDialog()
689 //=================================================================================
690 void SMESHGUI_MG_ADAPTDRIVER::deactivateActiveDialog()
693 if (ConstructorsBox->isEnabled()) {
694 ConstructorsBox->setEnabled(false);
695 GroupArguments->setEnabled(false);
696 GroupButtons->setEnabled(false);
697 mySMESHGUI->ResetState();
698 mySMESHGUI->SetActiveDialogBox(0);
700 selMgr->removeFilter( myIdSourceFilter );
704 //=================================================================================
705 // function : ActivateThisDialog()
707 //=================================================================================
708 void SMESHGUI_MG_ADAPTDRIVER::activateThisDialog()
711 /* Emit a signal to deactivate the active dialog */
712 // mySMESHGUI->EmitSignalDeactivateDialog();
713 // ConstructorsBox->setEnabled(true);
714 // GroupArguments->setEnabled(true);
715 // GroupButtons->setEnabled(true);
717 // mySMESHGUI->SetActiveDialogBox((QDialog*)this);
719 // onSelectIdSource( myIdSourceCheck->isChecked() );
721 // SelectionIntoArgument();
724 //=================================================================================
725 // function : setFilters()
726 // purpose : SLOT. Called when "Filter" button pressed.
727 //=================================================================================
728 void SMESHGUI_MG_ADAPTDRIVER::setFilters()
730 if(myMesh->_is_nil()) {
731 SUIT_MessageBox::critical(this,
733 tr("NO_MESH_SELECTED"));
737 myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
740 if ( myMesh->NbEdges() ) types << SMESH::EDGE;
741 if ( myMesh->NbFaces() ) types << SMESH::FACE;
742 if ( myMesh->NbVolumes() ) types << SMESH::VOLUME;
743 if ( myMesh->NbBalls() ) types << SMESH::BALL;
744 if ( myMesh->Nb0DElements()) types << SMESH::ELEM0D;
745 if ( types.count() > 1 ) types << SMESH::ALL;
747 myFilterDlg->Init( types );
748 myFilterDlg->SetSelection();
749 myFilterDlg->SetMesh( myMesh );
750 myFilterDlg->SetSourceWg( myLineEditElements );
755 //=================================================================================
756 // function : onOpenView()
758 //=================================================================================
759 void SMESHGUI_MG_ADAPTDRIVER::onOpenView()
762 SMESH::SetPointRepresentation(false);
765 mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
766 activateThisDialog();
770 //=================================================================================
771 // function : onCloseView()
773 //=================================================================================
774 void SMESHGUI_MG_ADAPTDRIVER::onCloseView()
776 deactivateActiveDialog();