Salome HOME
Fix for the '52934: Elements are't not highlighted in vtk viewer after set id in...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Measurements.cxx
index 13a2092f835dcbf9a1615e9e7b73e5c3a9d19783..c58a8c9c67fee4d967dc45197820425587a1fec4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -36,7 +36,7 @@
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_ResourceMgr.h>
 #include <SVTK_ViewWindow.h>
-#include <SALOME_ListIteratorOfListIO.hxx>
+#include <SALOME_ListIO.hxx>
 
 #include <QButtonGroup>
 #include <QGridLayout>
@@ -198,6 +198,7 @@ SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent )
   clear();
 
   //setTarget( FirstTgt );
+  selectionChanged();
 }
 
 /*!
@@ -367,6 +368,7 @@ void SMESHGUI_MinDistance::createPreview( double x1, double y1, double z1, doubl
   myPreview = SALOME_Actor::New();
   myPreview->PickableOff();
   myPreview->SetMapper( aMapper );
+  myPreview->SetResolveCoincidentTopology(true);
   aMapper->Delete();
   vtkProperty* aProp = vtkProperty::New();
   aProp->SetRepresentationToWireframe();
@@ -500,13 +502,21 @@ void SMESHGUI_MinDistance::secondEdited()
   setTarget( SecondTgt );
   if ( sender() == mySecondTgt )
     clear();
+  QString text = mySecondTgt->text();
+  if ( !mySecondActor )
+  {
+    selectionChanged();
+    mySecondTgt->setText( text );
+  }
   SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
   if ( mySecondActor && selector ) {
     Handle(SALOME_InteractiveObject) IO = mySecondActor->getIO();
     if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) {
-      TColStd_MapOfInteger ID;
-      ID.Add( mySecondTgt->text().toLong() );
-      selector->AddOrRemoveIndex( IO, ID, false );
+      if ( !text.isEmpty() ) {
+        TColStd_MapOfInteger ID;
+        ID.Add( text.toLong() );
+        selector->AddOrRemoveIndex( IO, ID, false );
+      }
     }
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
       aViewWindow->highlight( IO, true, true );
@@ -519,8 +529,8 @@ void SMESHGUI_MinDistance::secondEdited()
 void SMESHGUI_MinDistance::compute()
 {
   SUIT_OverrideCursor wc;
-  SMESH::SMESH_IDSource_var s1;
-  SMESH::SMESH_IDSource_var s2;
+  SMESH::IDSource_wrap s1;
+  SMESH::IDSource_wrap s2;
   bool isOrigin = mySecond->checkedId() == OriginTgt;
 
   // process first target
@@ -538,6 +548,7 @@ void SMESHGUI_MinDistance::compute()
     }
     else {
       s1 = myFirstSrc;
+      s1->Register();
     }
   }
 
@@ -556,6 +567,7 @@ void SMESHGUI_MinDistance::compute()
     }
     else {
       s2 = mySecondSrc;
+      s2->Register();
     }
   }
 
@@ -758,7 +770,8 @@ void SMESHGUI_BoundingBox::updateSelection()
 
   sourceEdited();
 
-  //selectionChanged();
+  if ( mySource->text().isEmpty() )
+    selectionChanged();
 }
 
 /*!
@@ -1035,14 +1048,17 @@ void SMESHGUI_BoundingBox::compute()
   }
   else {
     srcList->length( mySrc.count() );
-    for( int i = 0; i < mySrc.count(); i++ )
+    for( int i = 0; i < mySrc.count(); i++ ) {
       srcList[i] = mySrc[i];
+      mySrc[i]->Register();
+    }
   }
   if ( srcList->length() > 0 ) {
     // compute bounding box
     int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
     SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
     SMESH::Measure result = measure->BoundingBox( srcList.in() );
+    SALOME::UnRegister( srcList );
     measure->UnRegister();
     myXmin->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
     myXmax->setText( QString::number( result.maxX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
@@ -1080,6 +1096,222 @@ void SMESHGUI_BoundingBox::clear()
   erasePreview();
 }
 
+/*!
+  \class SMESHGUI_BasicProperties
+  \brief basic properties measurement widget.
+  
+  Widget to calculate length, area or volume for the selected object(s).
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
+*/
+SMESHGUI_BasicProperties::SMESHGUI_BasicProperties( QWidget* parent )
+: QWidget( parent )
+{
+  // Property (length, area or volume)
+  QGroupBox* aPropertyGrp = new QGroupBox( tr( "PROPERTY" ), this );
+
+  QRadioButton* aLength = new QRadioButton( tr( "LENGTH" ), aPropertyGrp );
+  QRadioButton* anArea = new QRadioButton( tr( "AREA" ), aPropertyGrp );
+  QRadioButton* aVolume = new QRadioButton( tr( "VOLUME" ), aPropertyGrp );
+
+  myMode = new QButtonGroup( this );
+  myMode->addButton( aLength, Length );
+  myMode->addButton( anArea, Area );
+  myMode->addButton( aVolume, Volume );
+
+  QHBoxLayout* aPropertyLayout = new QHBoxLayout;
+  aPropertyLayout->addWidget( aLength );
+  aPropertyLayout->addWidget( anArea );
+  aPropertyLayout->addWidget( aVolume );
+
+  aPropertyGrp->setLayout( aPropertyLayout );
+
+  // Source object
+  QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE_MESH_SUBMESH_GROUP" ), this );
+
+  mySource = new QLineEdit( aSourceGrp );
+  mySource->setReadOnly( true );
+    
+  QHBoxLayout* aSourceLayout = new QHBoxLayout;
+  aSourceLayout->addWidget( mySource );
+  
+  aSourceGrp->setLayout( aSourceLayout );
+
+  // Compute button
+  QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
+
+  // Result of computation (length, area or volume)
+  myResultGrp = new QGroupBox( this );
+
+  myResult = new QLineEdit;
+  myResult->setReadOnly( true );
+
+  QHBoxLayout* aResultLayout = new QHBoxLayout;
+  aResultLayout->addWidget( myResult );
+  
+  myResultGrp->setLayout( aResultLayout );
+
+  // Layout
+  QGridLayout* aMainLayout = new QGridLayout( this );
+  aMainLayout->setMargin( MARGIN );
+  aMainLayout->setSpacing( SPACING );
+
+  aMainLayout->addWidget( aPropertyGrp, 0, 0, 1, 2 );
+  aMainLayout->addWidget( aSourceGrp, 1, 0, 1, 2 );
+  aMainLayout->addWidget( aCompute,   2, 0 );
+  aMainLayout->addWidget( myResultGrp, 3, 0, 1, 2 );
+  aMainLayout->setColumnStretch( 1, 5 );
+  aMainLayout->setRowStretch( 4, 5 );
+
+  // Initial state
+  setMode( Length );
+  
+  // Connections
+  connect( myMode, SIGNAL( buttonClicked( int ) ),  this, SLOT( modeChanged( int ) ) );
+  connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) );
+  
+  // Selection filter
+  QList<SUIT_SelectionFilter*> filters;
+  filters.append( new SMESH_TypeFilter( SMESH::MESHorSUBMESH ) );
+  filters.append( new SMESH_TypeFilter( SMESH::GROUP ) );
+  myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_BasicProperties::~SMESHGUI_BasicProperties()
+{
+}
+
+/*!
+  \brief Sets the measurement mode.
+  \param theMode the mode to set (length, area or volume meausurement)
+*/
+void SMESHGUI_BasicProperties::setMode( const Mode theMode )
+{
+  QRadioButton* aButton = qobject_cast<QRadioButton*>( myMode->button( theMode ) );
+  if ( aButton ) {
+    aButton->setChecked( true );
+    modeChanged( theMode );
+  }
+}
+
+/*!
+  \brief Setup the selection mode.
+*/
+void SMESHGUI_BasicProperties::updateSelection()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+
+  disconnect( selMgr, 0, this, 0 );
+  selMgr->clearFilters();
+  
+  SMESH::SetPointRepresentation( false );
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) {
+    aViewWindow->SetSelectionMode( ActorSelection );
+  }
+  selMgr->installFilter( myFilter );
+  
+  connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
+
+  if ( mySource->text().isEmpty() )
+    selectionChanged();
+}
+
+/*!
+  \brief Deactivate widget
+*/
+void SMESHGUI_BasicProperties::deactivate()
+{
+  disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
+}
+
+/*!
+  \brief Called when selection is changed
+*/
+void SMESHGUI_BasicProperties::selectionChanged()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+    if ( !CORBA::is_nil( obj ) ) {
+      mySrc = obj;
+
+      QString aName;
+      SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+      mySource->setText( aName );
+    }
+  }
+
+  clear();
+}
+
+/*!
+  \brief Called when the measurement mode selection is changed.
+  \param theMode the selected mode
+*/
+void SMESHGUI_BasicProperties::modeChanged( int theMode )
+{
+  clear();
+
+  if ( theMode == Length ) {
+    myResultGrp->setTitle( tr("LENGTH") );
+  } else if ( theMode == Area ) {
+    myResultGrp->setTitle( tr("AREA") );
+  } else if ( theMode == Volume ) {
+    myResultGrp->setTitle( tr("VOLUME") );
+  }
+}
+
+/*!
+  \brief Calculate length, area or volume for the selected object(s)
+*/
+void SMESHGUI_BasicProperties::compute()
+{
+  SUIT_OverrideCursor wc;
+
+  SMESH::SMESH_IDSource_var source;
+
+  if ( !CORBA::is_nil( mySrc ) ) {
+    // compute
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
+
+    double result = 0;
+
+    if ( myMode->checkedId() == Length ) {
+      result = measure->Length( mySrc.in() );
+    } else if ( myMode->checkedId() == Area ) {
+      result = measure->Area( mySrc.in() );
+    } else if ( myMode->checkedId() == Volume ) {
+      result = measure->Volume( mySrc.in() );
+    }
+    
+    measure->UnRegister();
+
+    myResult->setText( QString::number( result, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+  } else {
+    clear();
+  }
+}
+
+/*!
+  \brief Reset the widget to the initial state (nullify the result field)
+*/
+void SMESHGUI_BasicProperties::clear()
+{
+  myResult->clear();
+}
+
 /*!
   \class SMESHGUI_MeshInfoDlg
   \brief Centralized dialog box for the measurements
@@ -1105,12 +1337,17 @@ SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page )
   // min distance
 
   myMinDist = new SMESHGUI_MinDistance( myTabWidget );
-  myTabWidget->addTab( myMinDist, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_MIN_DIST" ) ), tr( "MIN_DIST" ) );
+  int aMinDistInd = myTabWidget->addTab( myMinDist, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_MIN_DIST" ) ), tr( "MIN_DIST" ) );
 
   // bounding box
   
   myBndBox = new SMESHGUI_BoundingBox( myTabWidget );
-  myTabWidget->addTab( myBndBox, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BND_BOX" ) ), tr( "BND_BOX" ) );
+  int aBndBoxInd = myTabWidget->addTab( myBndBox, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BND_BOX" ) ), tr( "BND_BOX" ) );
+
+  // basic properties
+  
+  myBasicProps = new SMESHGUI_BasicProperties( myTabWidget );
+  int aBasicPropInd = myTabWidget->addTab( myBasicProps, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BASIC_PROPS" ) ), tr( "BASIC_PROPERTIES" ) );
 
   // buttons
   QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
@@ -1134,7 +1371,19 @@ SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page )
   l->addStretch();
   l->addLayout( btnLayout );
 
-  myTabWidget->setCurrentIndex( qMax( (int)MinDistance, qMin( (int)BoundingBox, page ) ) );
+  int anInd = -1;
+  if ( page == MinDistance ) {
+    anInd = aMinDistInd;
+  } else if ( page == BoundingBox ) {
+    anInd = aBndBoxInd;
+  } else if ( page == Length || page == Area || page == Volume ) {
+    myBasicProps->setMode( (SMESHGUI_BasicProperties::Mode)(page - Length) );
+    anInd = aBasicPropInd;
+  }
+
+  if ( anInd >= 0 ) {
+    myTabWidget->setCurrentIndex( anInd );
+  }
 
   connect( okBtn,       SIGNAL( clicked() ),              this, SLOT( reject() ) );
   connect( helpBtn,     SIGNAL( clicked() ),              this, SLOT( help() ) );
@@ -1195,7 +1444,10 @@ void SMESHGUI_MeasureDlg::updateSelection()
     myMinDist->updateSelection();
   else if ( myTabWidget->currentIndex() == BoundingBox )
     myBndBox->updateSelection();
-    
+  else {
+    myBndBox->erasePreview();
+    myBasicProps->updateSelection();
+  }
 }
 
 /*!
@@ -1203,9 +1455,16 @@ void SMESHGUI_MeasureDlg::updateSelection()
 */
 void SMESHGUI_MeasureDlg::help()
 {
-  SMESH::ShowHelpFile( myTabWidget->currentIndex() == MinDistance ?
-                       "measurements_page.html#min_distance_anchor" : 
-                       "measurements_page.html#bounding_box_anchor" );
+  QString aHelpFile;
+  if ( myTabWidget->currentIndex() == MinDistance ) {
+    aHelpFile = "measurements_page.html#min_distance_anchor";
+  } else if ( myTabWidget->currentIndex() == BoundingBox ) {
+    aHelpFile = "measurements_page.html#bounding_box_anchor";
+  } else {
+    aHelpFile = "measurements_page.html#basic_properties_anchor";
+  }
+
+  SMESH::ShowHelpFile( aHelpFile );
 }
 
 /*!
@@ -1224,6 +1483,7 @@ void SMESHGUI_MeasureDlg::activate()
 */
 void SMESHGUI_MeasureDlg::deactivate()
 {
+  myBasicProps->deactivate();
   myMinDist->deactivate();
   myBndBox->deactivate();
   myTabWidget->setEnabled( false );