Salome HOME
Task: "XAO format: fields on geometry".
authorouv <ouv@opencascade.com>
Fri, 18 Oct 2013 14:00:58 +0000 (14:00 +0000)
committerouv <ouv@opencascade.com>
Fri, 18 Oct 2013 14:00:58 +0000 (14:00 +0000)
Sub-task: "GUI/visualization - OCC viewer".

13 files changed:
doc/salome/gui/GEOM/images/pref15.png
doc/salome/gui/GEOM/input/geometry_preferences.doc
resources/SalomeApp.xml.in
src/DisplayGUI/DisplayGUI.cxx
src/EntityGUI/EntityGUI_FieldDlg.cxx
src/EntityGUI/EntityGUI_FieldDlg.h
src/GEOMGUI/GEOM_Displayer.cxx
src/GEOMGUI/GEOM_Displayer.h
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GeometryGUI.cxx
src/GEOMGUI/GeometryGUI.h
src/OBJECT/GEOM_AISShape.cxx
src/OBJECT/GEOM_AISShape.hxx

index b3b4df0f2a084feca2a1dbadc2f0abd01100726d..82189e99d19faeb08d54c81ecb5bd66f285af24f 100755 (executable)
Binary files a/doc/salome/gui/GEOM/images/pref15.png and b/doc/salome/gui/GEOM/images/pref15.png differ
index ab98a8281cf7733296d0b56e4a213c35d4df97ef..81090266aa76798fa4be45b3b16965aa831fa965 100644 (file)
@@ -94,6 +94,18 @@ system immediately after the module activation.</li>
 </ul>
 </ul>
 
+<ul>
+<li><b>Scalar bar for field presentation</b></li>
+<ul>
+<li><b>X position</b> - allows to define the parametric X position of the scalar bar.</li>
+<li><b>Y position</b> - allows to define the parametric Y position of the scalar bar.</li>
+<li><b>Width</b> - allows to define the parametric width of the scalar bar.</li>
+<li><b>Height</b> - allows to define the parametric height of the scalar bar.</li>
+<li><b>Text height</b> - allows to define the font height of the scalar bar labels.</li>
+<li><b>Number of intervals</b> - allows to define the number of scalar bar intervals.</li>
+</ul>
+</ul>
+
 
 <ul>
 <li><b>Operations</b></li>
index 73bb3172e49e490a51e247c7fe14f661d3826a6e..af5f33ef5dad888ba099ea0935f554badf90ba96 100644 (file)
     <parameter name="iso_number_u"        value="0" />
     <parameter name="iso_number_v"        value="0" />
 
+    <!-- Scalar bar for field step presentation -->
+    <parameter name="scalar_bar_x_position"   value="0.05" />
+    <parameter name="scalar_bar_y_position"   value="0.1" />
+    <parameter name="scalar_bar_width"        value="0.2" />
+    <parameter name="scalar_bar_height"       value="0.5" />
+    <parameter name="scalar_bar_text_height"  value="14" />
+    <parameter name="scalar_bar_nb_intervals" value="20" />
+
     <!-- Input field precisions -->
     <parameter name="def_precision"       value="3"  />
     <parameter name="length_precision"    value="6"  />
index fee7c9787ea0ec074c4a1249c6acffbec723bf21..c4432718ce7dd9644c869216414c34421143eb16 100644 (file)
@@ -88,6 +88,9 @@ bool DisplayGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent)
   SalomeApp_Application* app = getGeometryGUI()->getApp();
   if (!app) return false;
 
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+  if ( !appStudy ) return false;
+
   LightApp_SelectionMgr *Sel = app->selectionMgr();
   SALOME_ListIO selected;
   Sel->selectedObjects( selected );
@@ -150,6 +153,7 @@ bool DisplayGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent)
     break;
   }
   Sel->setSelectedObjects( selected );
+  GEOM_Displayer( appStudy ).UpdateColorScale();
   return true;
 }
 
index 9b4246b200c03e36184b9747dbe04f8c85da86e7..d6465df756a34acb8d1f957b537865cfeb1aacb2 100644 (file)
@@ -915,6 +915,16 @@ EntityGUI_FieldDlg::~EntityGUI_FieldDlg()
   }
   // if ( !myField->_is_nil())
   //   aDisplayer->Display(myField);
+
+  QListIterator<int> anIter( myHiddenFieldStepIds );
+  while( anIter.hasNext() )
+  {
+    const int aStepId = anIter.next();
+    GEOM::GEOM_FieldStep_var step = myField->GetStep( aStepId );
+    if( !step->_is_nil() )
+      aDisplayer->Display( step, false );
+  }
+  aDisplayer->UpdateViewer();
 }
 
 //=================================================================================
@@ -924,6 +934,7 @@ EntityGUI_FieldDlg::~EntityGUI_FieldDlg()
 void EntityGUI_FieldDlg::Init()
 {
   myDmMode = -1;
+  myHiddenFieldStepIds.clear();
   myStepsCombo->clear();
 
   if ( myIsCreation || myField->_is_nil() )
@@ -950,6 +961,29 @@ void EntityGUI_FieldDlg::Init()
   }
   else // edition
   {
+    // 1) get and sort step IDs
+    // 2) hide all displayed field steps' presentations
+    GEOM_Displayer* aDisplayer = getDisplayer();
+    GEOM::ListOfLong_var stepIDs = myField->GetSteps();
+    size_t i;
+    QList< int > stepsList;
+    for ( i = 0; i < stepIDs->length(); ++i )
+    {
+      int aStepId = stepIDs[i];
+      stepsList.push_back( aStepId );
+      GEOM::GEOM_FieldStep_var step = myField->GetStep( aStepId );
+      if( !step->_is_nil() )
+      {
+        QString anEntry( step->GetStudyEntry() );
+        if( aDisplayer->IsDisplayed( anEntry ) )
+        {
+          aDisplayer->Erase( step, false, false );
+          myHiddenFieldStepIds << aStepId;
+        }
+      }
+    }
+    qSort( stepsList.begin(), stepsList.end() );
+
     myIsCreation = false;
 
     CORBA::String_var fName = myField->GetName();
@@ -975,15 +1009,8 @@ void EntityGUI_FieldDlg::Init()
     myDimCombo->setEnabled( false );
     myNbCompsSpin->setEnabled( false );
 
-    // get and sort step IDs
-    GEOM::ListOfLong_var stepIDs = myField->GetSteps();
-    QList< int > stepsList;
-    for ( size_t i = 0; i < stepIDs->length(); ++i )
-      stepsList.push_back( stepIDs[i] );
-    qSort( stepsList.begin(), stepsList.end() );
-
     myStepsCombo->blockSignals( true );
-    for ( size_t i = 0; i < stepIDs->length(); ++i )
+    for ( i = 0; i < stepIDs->length(); ++i )
     {
       myStepsCombo->insertItem( i, QString::number( stepsList[i] ));
       if ( myCurStepID == stepsList[i] )
@@ -1854,7 +1881,14 @@ bool EntityGUI_FieldDlg::execute()
       }
     }
     tbl->setValues( step );
+
+    // update the presentation if it is displayed
+    CORBA::String_var aStepEntry = step->GetStudyEntry();
+    Handle(SALOME_InteractiveObject) aStepIO =
+      new SALOME_InteractiveObject( aStepEntry.in(), "GEOM", "TEMP_IO" );
+    getDisplayer()->Redisplay( aStepIO, false, false );
   }
+  getDisplayer()->UpdateViewer();
 
   // remove steps
   if ( !myIsCreation )
index c3a0b7ae1d958b442f55ae55a025ab93feb52a5a..01dd762ffc941d1e1dacc9f3416400e9aef9c8b1 100644 (file)
@@ -120,6 +120,8 @@ private:
   int                                 myDmMode;
   bool                                myIsHiddenMain;
 
+  QList<int>                          myHiddenFieldStepIds;
+
   QPushButton*                        myShapeSelBtn;
   QLineEdit*                          myShapeName;
   QComboBox*                          myTypeCombo;
index fca01937933bf472db9c3b6a095ce0be0103b75d..9e59ce7e2f9b0a52ebaab26fc92409e3da391b7e 100644 (file)
 #include <SVTK_Prs.h>
 #include <SVTK_ViewModel.h>
 
+#include <OCCViewer_ViewWindow.h>
+#include <OCCViewer_ViewPort3d.h>
+
 // OCCT Includes
 #include <AIS_Drawer.hxx>
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
+#include <Aspect_ColorScale.hxx>
 #include <Prs3d_IsoAspect.hxx>
 #include <Prs3d_PointAspect.hxx>
 #include <StdSelect_TypeOfEdge.hxx>
@@ -258,7 +262,7 @@ SUIT_SelectionFilter* GEOM_Displayer::getComplexFilter( const QList<int>* aSubSh
 // Function : getEntry
 // Purpose  :
 //================================================================
-static std::string getEntry( GEOM::GEOM_Object_ptr object )
+static std::string getEntry( GEOM::GEOM_BaseObject_ptr object )
 {
   SUIT_Session* session = SUIT_Session::session();
   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
@@ -280,7 +284,7 @@ static std::string getEntry( GEOM::GEOM_Object_ptr object )
 // Function : getName
 // Purpose  :
 //================================================================
-static std::string getName( GEOM::GEOM_Object_ptr object )
+static std::string getName( GEOM::GEOM_BaseObject_ptr object )
 {
   SUIT_Session* session = SUIT_Session::session();
   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
@@ -359,6 +363,11 @@ GEOM_Displayer::GEOM_Displayer( SalomeApp_Study* st )
   #endif
 
   myViewFrame = 0;
+
+  myFieldDataType = GEOM::FDT_Double;
+  myFieldDimension = 0;
+  myFieldStepRangeMin = 0;
+  myFieldStepRangeMax = 0;
 }
 
 //=================================================================
@@ -413,7 +422,7 @@ void GEOM_Displayer::Display( const Handle(SALOME_InteractiveObject)& theIO,
  *  not using dialog boxes.
  */
 //=================================================================
-void GEOM_Displayer::Display( GEOM::GEOM_Object_ptr theObj, const bool updateViewer )
+void GEOM_Displayer::Display( GEOM::GEOM_BaseObject_ptr theObj, const bool updateViewer )
 {
   if ( theObj->_is_nil() )
     return;
@@ -466,7 +475,7 @@ void GEOM_Displayer::Erase( const Handle(SALOME_InteractiveObject)& theIO,
  *  Erase geometry object in the current viewer
  */
 //=================================================================
-void GEOM_Displayer::Erase( GEOM::GEOM_Object_ptr theObj,
+void GEOM_Displayer::Erase( GEOM::GEOM_BaseObject_ptr theObj,
                             const bool forced,
                             const bool updateViewer )
 {
@@ -486,7 +495,8 @@ void GEOM_Displayer::Erase( GEOM::GEOM_Object_ptr theObj,
  */
 //=================================================================
 void GEOM_Displayer::Redisplay( const Handle(SALOME_InteractiveObject)& theIO,
-                                const bool updateViewer )
+                                const bool updateViewer,
+                                const bool checkActiveViewer )
 {
   // Remove the object permanently (<forced> == true)
   SUIT_Session* ses = SUIT_Session::session();
@@ -508,7 +518,7 @@ void GEOM_Displayer::Redisplay( const Handle(SALOME_InteractiveObject)& theIO,
           SALOME_View* view = dynamic_cast<SALOME_View*>(vmodel);
           if ( view )
           {
-            if ( view->isVisible( theIO ) || view == GetActiveView() )
+            if ( view->isVisible( theIO ) || ( checkActiveViewer && view == GetActiveView() ) )
             {
               Erase( theIO, true, false, view );
               Display( theIO, updateViewer, view );
@@ -759,6 +769,14 @@ void GEOM_Displayer::updateShapeProperties( const Handle(GEOM_AISShape)& AISShap
     }
   }
 
+  // set field step data
+  AISShape->setFieldStepInfo( myFieldDataType,
+                              myFieldDimension,
+                              myFieldStepData,
+                              myFieldStepName,
+                              myFieldStepRangeMin,
+                              myFieldStepRangeMax );
+
   if ( create && !isTemporary && aMgrId != -1 ) {
     // set properties to the study
     study->setObjectPropMap( aMgrId, entry, propMap );
@@ -936,11 +954,13 @@ void GEOM_Displayer::Erase( const SALOME_ListIO& theIOList,
  *  Calls Redisplay() method for each object in the given list
  */
 //=================================================================
-void GEOM_Displayer::Redisplay( const SALOME_ListIO& theIOList, const bool updateViewer )
+void GEOM_Displayer::Redisplay( const SALOME_ListIO& theIOList,
+                                const bool updateViewer,
+                                const bool checkActiveViewer )
 {
   SALOME_ListIteratorOfListIO Iter( theIOList );
   for ( ; Iter.More(); Iter.Next() )
-    Redisplay( Iter.Value(), false );
+    Redisplay( Iter.Value(), false, checkActiveViewer );
 
   if ( updateViewer )
     UpdateViewer();
@@ -1276,13 +1296,34 @@ SALOME_Prs* GEOM_Displayer::buildPresentation( const QString& entry,
               CORBA::Object_var object = GeometryGUI::ClientSObjectToObject(SO);
               if ( !CORBA::is_nil( object ) )
               {
-                // downcast to GEOM object
-                GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( object );
-                if ( !GeomObject->_is_nil() )
+                // downcast to GEOM base object
+                GEOM::GEOM_BaseObject_var GeomBaseObject = GEOM::GEOM_BaseObject::_narrow( object );
+                if ( !GeomBaseObject->_is_nil() )
                 {
-                  // finally set shape
-                  setShape( GEOM_Client::get_client().GetShape( GeometryGUI::GetGeomGen(), GeomObject ) );
-                  myType = GeomObject->GetType();
+                  myType = GeomBaseObject->GetType();
+
+                  // downcast to GEOM object
+                  GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
+                  if ( myType == GEOM_FIELD_STEP )
+                  {
+                    // get the GEOM object from the field's shape
+                    GEOM::GEOM_FieldStep_var GeomFieldStep = GEOM::GEOM_FieldStep::_narrow( GeomBaseObject );
+                    if ( !GeomFieldStep->_is_nil() )
+                    {
+                      GEOM::GEOM_Field_var GeomField = GeomFieldStep->GetField();
+                      if ( !GeomField->_is_nil() )
+                        GeomObject = GeomField->GetShape();
+                    }
+
+                    // read the field step information
+                    readFieldStepInfo( GeomFieldStep );
+                  }
+
+                  if ( !GeomObject->_is_nil() )
+                  {
+                    // finally set shape
+                    setShape( GEOM_Client::get_client().GetShape( GeometryGUI::GetGeomGen(), GeomObject ) );
+                  }
                 }
               }
             }
@@ -1344,6 +1385,13 @@ void GEOM_Displayer::internalReset()
 {
   myIO.Nullify();
   myShape.Nullify();
+
+  myFieldDataType = GEOM::FDT_Double;
+  myFieldDimension = 0;
+  myFieldStepData.clear();
+  myFieldStepName.Clear();
+  myFieldStepRangeMin = 0;
+  myFieldStepRangeMax = 0;
 }
 
 //=================================================================
@@ -1542,6 +1590,13 @@ void GEOM_Displayer::AfterDisplay( SALOME_View* v, const SALOME_OCCPrs* p )
       }
     }
   }
+  UpdateColorScale();
+}
+
+void GEOM_Displayer::AfterErase( SALOME_View* v, const SALOME_OCCPrs* p )
+{
+  LightApp_Displayer::AfterErase( v, p );
+  UpdateColorScale();
 }
 
 //=================================================================
@@ -1709,12 +1764,29 @@ void GEOM_Displayer::setShape( const TopoDS_Shape& theShape )
   myShape = theShape;
 }
 
+void GEOM_Displayer::setFieldStepInfo( const GEOM::field_data_type theFieldDataType,
+                                       const int theFieldDimension,
+                                       const QList<QVariant>& theFieldStepData,
+                                       const TCollection_AsciiString& theFieldStepName,
+                                       const double theFieldStepRangeMin,
+                                       const double theFieldStepRangeMax )
+{
+  myFieldDataType = theFieldDataType;
+  myFieldDimension = theFieldDimension;
+  myFieldStepData = theFieldStepData;
+  myFieldStepName = theFieldStepName;
+  myFieldStepRangeMin = theFieldStepRangeMin;
+  myFieldStepRangeMax = theFieldStepRangeMax;
+}
+
 bool GEOM_Displayer::canBeDisplayed( const QString& entry, const QString& viewer_type ) const
 {
   _PTR(SObject) anObj = getStudy()->studyDS()->FindObjectID( (const char*)entry.toLatin1() );
   GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(anObj)); // enable displaying of GEOM objects
+  GEOM::GEOM_FieldStep_var aFieldStepObj = GEOM::GEOM_FieldStep::_narrow(GeometryGUI::ClientSObjectToObject(anObj)); // enable displaying of GEOM field steps
   GEOM::GEOM_Gen_var aCompObj = GEOM::GEOM_Gen::_narrow(GeometryGUI::ClientSObjectToObject(anObj)); // enable displaying of whole GEOM component
-  return ( !CORBA::is_nil( aGeomObj ) || !CORBA::is_nil( aCompObj ) ) && (viewer_type == SOCC_Viewer::Type() || viewer_type == SVTK_Viewer::Type());
+  return ( !CORBA::is_nil( aGeomObj ) || !CORBA::is_nil( aFieldStepObj ) || !CORBA::is_nil( aCompObj ) ) &&
+         (viewer_type == SOCC_Viewer::Type() || viewer_type == SVTK_Viewer::Type());
 }
 
 int GEOM_Displayer::SetDisplayMode( const int theMode )
@@ -1876,36 +1948,38 @@ PropMap GEOM_Displayer::getObjectProperties( SalomeApp_Study* study,
           CORBA::Object_var object = GeometryGUI::ClientSObjectToObject( SO );
           if ( !CORBA::is_nil( object ) ) {
             GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_narrow( object );
-            // check that geom object has color properly set
-            bool hasColor = false;
-            SALOMEDS::Color aSColor = getColor( geomObject, hasColor );
-            // set color from geometry object (only once, if it is not yet set in GUI)
-            // current implementation is to use same color for all aspects
-            // (TODO) possible future improvements about free boundaries, standalone edges etc colors can be here
-            if ( hasColor && !storedMap.contains( GEOM::propertyName( GEOM::Color ) ) ) {
-              QColor objColor = QColor::fromRgbF( aSColor.R, aSColor.G, aSColor.B );
-              propMap.insert( GEOM::propertyName( GEOM::ShadingColor ),   objColor );
-              propMap.insert( GEOM::propertyName( GEOM::WireframeColor ), objColor );
-              propMap.insert( GEOM::propertyName( GEOM::LineColor ),      objColor );
-              propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ),   objColor );
-              propMap.insert( GEOM::propertyName( GEOM::PointColor ),     objColor );
-            }
-            // check that object has point marker properly set
-            GEOM::marker_type mType = geomObject->GetMarkerType();
-            GEOM::marker_size mSize = geomObject->GetMarkerSize();
-            int mTextureId = geomObject->GetMarkerTexture();
-            bool hasMarker = ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER && mSize > GEOM::MS_NONE && mSize <= GEOM::MS_70 ) || 
-                             ( mType == GEOM::MT_USER && mTextureId > 0 );
-            // set point marker from geometry object (only once, if it is not yet set in GUI)
-            if ( hasMarker && !storedMap.contains( GEOM::propertyName( GEOM::PointMarker ) ) ) {
-              if ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER ) {
-                // standard type
-                propMap.insert( GEOM::propertyName( GEOM::PointMarker ),
-                                QString( "%1%2%3" ).arg( (int)mType ).arg( GEOM::subSectionSeparator() ).arg( (int)mSize ) );
+            if ( !CORBA::is_nil( geomObject ) ) { // to check
+              // check that geom object has color properly set
+              bool hasColor = false;
+              SALOMEDS::Color aSColor = getColor( geomObject, hasColor );
+              // set color from geometry object (only once, if it is not yet set in GUI)
+              // current implementation is to use same color for all aspects
+              // (TODO) possible future improvements about free boundaries, standalone edges etc colors can be here
+              if ( hasColor && !storedMap.contains( GEOM::propertyName( GEOM::Color ) ) ) {
+                QColor objColor = QColor::fromRgbF( aSColor.R, aSColor.G, aSColor.B );
+                propMap.insert( GEOM::propertyName( GEOM::ShadingColor ),   objColor );
+                propMap.insert( GEOM::propertyName( GEOM::WireframeColor ), objColor );
+                propMap.insert( GEOM::propertyName( GEOM::LineColor ),      objColor );
+                propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ),   objColor );
+                propMap.insert( GEOM::propertyName( GEOM::PointColor ),     objColor );
               }
-              else if ( mType == GEOM::MT_USER ) {
-                // custom texture
-                propMap.insert( GEOM::propertyName( GEOM::PointMarker ), QString::number( mTextureId ) );
+              // check that object has point marker properly set
+              GEOM::marker_type mType = geomObject->GetMarkerType();
+              GEOM::marker_size mSize = geomObject->GetMarkerSize();
+              int mTextureId = geomObject->GetMarkerTexture();
+              bool hasMarker = ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER && mSize > GEOM::MS_NONE && mSize <= GEOM::MS_70 ) || 
+                               ( mType == GEOM::MT_USER && mTextureId > 0 );
+              // set point marker from geometry object (only once, if it is not yet set in GUI)
+              if ( hasMarker && !storedMap.contains( GEOM::propertyName( GEOM::PointMarker ) ) ) {
+                if ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER ) {
+                  // standard type
+                  propMap.insert( GEOM::propertyName( GEOM::PointMarker ),
+                                  QString( "%1%2%3" ).arg( (int)mType ).arg( GEOM::subSectionSeparator() ).arg( (int)mSize ) );
+                }
+                else if ( mType == GEOM::MT_USER ) {
+                  // custom texture
+                  propMap.insert( GEOM::propertyName( GEOM::PointMarker ), QString::number( mTextureId ) );
+                }
               }
             }
           }
@@ -2110,3 +2184,374 @@ void GEOM_Displayer::EraseWithChildren(const Handle(SALOME_InteractiveObject)& t
       view->Repaint();
   }
 }
+
+void GEOM_Displayer::readFieldStepInfo( GEOM::GEOM_FieldStep_var theGeomFieldStep )
+{
+  if( theGeomFieldStep->_is_nil() )
+    return;
+
+  GEOM::GEOM_Field_var aGeomField = theGeomFieldStep->GetField();
+  if( aGeomField->_is_nil() )
+    return;
+
+  GEOM::GEOM_Object_var aGeomFieldShape = aGeomField->GetShape();
+  if( aGeomFieldShape->_is_nil() )
+    return;
+
+  TCollection_AsciiString aFieldStepName( theGeomFieldStep->GetName() );
+  TCollection_AsciiString aFieldName( aGeomField->GetName() );
+  TCollection_AsciiString aShapeName( aGeomFieldShape->GetName() );
+
+  aFieldStepName = aShapeName + "\n" + aFieldName + "\n" + aFieldStepName;
+
+  GEOM::field_data_type aFieldDataType = aGeomField->GetDataType();
+
+  int aFieldDimension = aGeomField->GetDimension();
+
+  GEOM::string_array_var aFieldComponents = aGeomField->GetComponents();
+  int aFieldNbComponents = aFieldComponents->length();
+
+  QList<QVariant> aFieldStepData;
+  if( aFieldDataType == GEOM::FDT_Bool )
+  {
+    GEOM::GEOM_BoolFieldStep_var aGeomBoolFieldStep = GEOM::GEOM_BoolFieldStep::_narrow( theGeomFieldStep );
+    if ( !aGeomBoolFieldStep->_is_nil() )
+    {
+      GEOM::short_array_var aValues = aGeomBoolFieldStep->GetValues();
+      for( size_t i = 0, n = aValues->length(); i < n; i++ )
+        aFieldStepData << (bool)aValues[i];
+    }
+  }
+  else if( aFieldDataType == GEOM::FDT_Int )
+  {
+    GEOM::GEOM_IntFieldStep_var aGeomIntFieldStep = GEOM::GEOM_IntFieldStep::_narrow( theGeomFieldStep );
+    if ( !aGeomIntFieldStep->_is_nil() )
+    {
+      GEOM::ListOfLong_var aValues = aGeomIntFieldStep->GetValues();
+      for( size_t i = 0, n = aValues->length(); i < n; i++ )
+        aFieldStepData << aValues[i];
+    }
+  }
+  else if( aFieldDataType == GEOM::FDT_Double )
+  {
+    GEOM::GEOM_DoubleFieldStep_var aGeomDoubleFieldStep = GEOM::GEOM_DoubleFieldStep::_narrow( theGeomFieldStep );
+    if ( !aGeomDoubleFieldStep->_is_nil() )
+    {
+      GEOM::ListOfDouble_var aValues = aGeomDoubleFieldStep->GetValues();
+      for( size_t i = 0, n = aValues->length(); i < n; i++ )
+        aFieldStepData << aValues[i];
+    }
+  }
+  else if( aFieldDataType == GEOM::FDT_String )
+  {
+    GEOM::GEOM_StringFieldStep_var aGeomStringFieldStep = GEOM::GEOM_StringFieldStep::_narrow( theGeomFieldStep );
+    if ( !aGeomStringFieldStep->_is_nil() )
+    {
+      GEOM::string_array_var aValues = aGeomStringFieldStep->GetValues();
+      for( size_t i = 0, n = aValues->length(); i < n; i++ )
+        aFieldStepData << QString( aValues[i] );
+    }
+  }
+
+  double aFieldStepRangeMin = 0, aFieldStepRangeMax = 0;
+  aFieldStepData = groupFieldData( aFieldStepData,
+                                   aFieldNbComponents,
+                                   aFieldDataType == GEOM::FDT_String,
+                                   aFieldStepRangeMin,
+                                   aFieldStepRangeMax );
+
+  setFieldStepInfo( aFieldDataType,
+                    aFieldDimension,
+                    aFieldStepData,
+                    aFieldStepName,
+                    aFieldStepRangeMin,
+                    aFieldStepRangeMax );
+}
+
+QList<QVariant> GEOM_Displayer::groupFieldData( const QList<QVariant>& theFieldStepData,
+                                                const int theFieldNbComponents,
+                                                const bool theIsString,
+                                                double& theFieldStepRangeMin,
+                                                double& theFieldStepRangeMax )
+{
+  QList<QVariant> aResultList;
+  theFieldStepRangeMin = 0;
+  theFieldStepRangeMax = 0;
+
+  if( theFieldStepData.isEmpty() || theFieldNbComponents < 1 )
+    return aResultList;
+
+  int aNbSubShapes = theFieldStepData.count() / theFieldNbComponents;
+
+  QList<QVariant> aGroupedList;
+
+  bool anIsBoolean = false;
+  for( int aSubShape = 0; aSubShape < aNbSubShapes; aSubShape++ )
+  {
+    double aNorm = 0;
+    QStringList aStringList;
+
+    int aBaseIndex = aSubShape * theFieldNbComponents;
+    for( int aComponent = 0; aComponent < theFieldNbComponents; aComponent++ )
+    {
+      int anIndex = aComponent + aBaseIndex;
+
+      const QVariant& aVariant = theFieldStepData[ anIndex ];
+      if( theIsString )
+      {
+        if( aVariant.type() == QVariant::String )
+          aStringList << aVariant.toString();
+      }
+      else
+      {
+        double aValue = 0;
+        if( aVariant.type() == QVariant::Bool )
+        {
+          aValue = aVariant.toBool() ? 1.0 : 0.0;
+          aNorm += aValue;
+          anIsBoolean = true;
+        }
+        else
+        {
+          if( aVariant.type() == QVariant::Int )
+            aValue = double( aVariant.toInt() );
+          else if( aVariant.type() == QVariant::Double )
+            aValue = aVariant.toDouble();
+          aNorm += aValue * aValue;
+        }
+      }
+    }
+
+    if( theIsString )
+      aGroupedList << aStringList.join( "\n" );
+    else
+    {
+      if( anIsBoolean )
+        aNorm /= theFieldNbComponents;
+      else
+        aNorm = pow( aNorm, 0.5 );
+
+      if( aGroupedList.isEmpty() )
+        theFieldStepRangeMin = theFieldStepRangeMax = aNorm;
+      else
+      {
+        theFieldStepRangeMin = Min( theFieldStepRangeMin, aNorm );
+        theFieldStepRangeMax = Max( theFieldStepRangeMax, aNorm );
+      }
+
+      aGroupedList << aNorm;
+    }
+  }
+
+  if( anIsBoolean )
+  {
+    theFieldStepRangeMin = 0.0;
+    theFieldStepRangeMax = 1.0;
+  }
+
+  SUIT_Session* session = SUIT_Session::session();
+  SUIT_ResourceMgr* resMgr = session->resourceMgr();
+  Standard_Integer aNbIntervals = resMgr->integerValue( "Geometry", "scalar_bar_nb_intervals", 20 );
+
+  QListIterator<QVariant> anIter( aGroupedList );
+  while( anIter.hasNext() )
+  {
+    const QVariant& aVariant = anIter.next();
+    if( theIsString )
+      aResultList << aVariant;
+    else
+    {
+      QColor aQColor;
+      Quantity_Color aColor;
+      if( FindColor( aVariant.toDouble(), theFieldStepRangeMin, theFieldStepRangeMax, anIsBoolean ? 2 : aNbIntervals, aColor ) )
+        aQColor = QColor::fromRgbF( aColor.Red(), aColor.Green(), aColor.Blue() );
+      aResultList << aQColor;
+    }
+  }
+  return aResultList;
+}
+
+// Note: the method is copied from Aspect_ColorScale class
+Standard_Integer GEOM_Displayer::HueFromValue( const Standard_Integer aValue,
+                                               const Standard_Integer aMin,
+                                               const Standard_Integer aMax )
+{
+  Standard_Integer minLimit( 0 ), maxLimit( 230 );
+
+  Standard_Integer aHue = maxLimit;
+  if ( aMin != aMax )
+    aHue = (Standard_Integer)( maxLimit - ( maxLimit - minLimit ) * ( aValue - aMin ) / ( aMax - aMin ) );
+
+  aHue = Min( Max( minLimit, aHue ), maxLimit );
+
+  return aHue;
+}
+
+// Note: the method is copied from Aspect_ColorScale class
+Standard_Boolean GEOM_Displayer::FindColor( const Standard_Real aValue, 
+                                            const Standard_Real aMin,
+                                            const Standard_Real aMax,
+                                            const Standard_Integer ColorsCount,
+                                            Quantity_Color& aColor )
+{
+  if( aValue<aMin || aValue>aMax || aMax<aMin )
+    return Standard_False;
+
+  else
+  {
+    Standard_Real IntervNumber = 0;
+    if( aValue<aMin )
+      IntervNumber = 0;
+    else if( aValue>aMax )
+      IntervNumber = ColorsCount-1;
+    else if( Abs( aMax-aMin ) > Precision::Approximation() )
+      IntervNumber = Floor( Standard_Real( ColorsCount ) * ( aValue - aMin ) / ( aMax - aMin ) ); // 'Ceiling' replaced with 'Floor'
+
+    Standard_Integer Interv = Standard_Integer( IntervNumber );
+
+    aColor = Quantity_Color( HueFromValue( Interv, 0, ColorsCount - 1 ), 1.0, 1.0, Quantity_TOC_HLS );
+
+    return Standard_True;
+  } 
+}
+
+void GEOM_Displayer::UpdateColorScale( const bool theIsRedisplayFieldSteps )
+{
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
+  if( !aStudy )
+    return;
+
+  SOCC_Viewer* aViewModel = dynamic_cast<SOCC_Viewer*>( GetActiveView() );
+  if( !aViewModel )
+    return;
+
+  Handle(V3d_Viewer) aViewer = aViewModel->getViewer3d();
+  if( aViewer.IsNull() )
+    return;
+
+  aViewer->InitActiveViews();
+  if( !aViewer->MoreActiveViews() )
+    return;
+
+  Handle(V3d_View) aView = aViewer->ActiveView();
+  if( aView.IsNull() )
+    return;
+
+  Standard_Boolean anIsDisplayColorScale = Standard_False;
+  TCollection_AsciiString aColorScaleTitle;
+  Standard_Real aColorScaleMin = 0, aColorScaleMax = 0;
+  Standard_Boolean anIsBoolean = Standard_False;
+
+  SALOME_ListIO aSelectedObjects;
+  myApp->selectionMgr()->selectedObjects( aSelectedObjects );
+  if( aSelectedObjects.Extent() == 1 )
+  {
+    Handle(SALOME_InteractiveObject) anIO = aSelectedObjects.First();
+    if( !anIO.IsNull() )
+    {
+      SOCC_Prs* aPrs = dynamic_cast<SOCC_Prs*>( aViewModel->CreatePrs( anIO->getEntry() ) );
+      if( aPrs )
+      {
+        AIS_ListOfInteractive aList;
+        aPrs->GetObjects( aList );
+        AIS_ListIteratorOfListOfInteractive anIter( aList );
+        for( ; anIter.More(); anIter.Next() )
+        {
+          Handle(GEOM_AISShape) aShape = Handle(GEOM_AISShape)::DownCast( anIter.Value() );
+          if( !aShape.IsNull() )
+          {
+            GEOM::field_data_type aFieldDataType;
+            int aFieldDimension;
+            QList<QVariant> aFieldStepData;
+            TCollection_AsciiString aFieldStepName;
+            double aFieldStepRangeMin, aFieldStepRangeMax;
+            aShape->getFieldStepInfo( aFieldDataType,
+                                      aFieldDimension,
+                                      aFieldStepData,
+                                      aFieldStepName,
+                                      aFieldStepRangeMin,
+                                      aFieldStepRangeMax );
+            if( !aFieldStepData.isEmpty() && aFieldDataType != GEOM::FDT_String )
+            {
+              anIsDisplayColorScale = Standard_True;
+              aColorScaleTitle = aFieldStepName;
+              aColorScaleMin = aFieldStepRangeMin;
+              aColorScaleMax = aFieldStepRangeMax;
+              anIsBoolean = aFieldDataType == GEOM::FDT_Bool;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if( anIsDisplayColorScale )
+  {
+    Handle(Aspect_ColorScale) aColorScale = aView->ColorScale();
+    if( !aColorScale.IsNull() )
+    {
+      SUIT_Session* session = SUIT_Session::session();
+      SUIT_ResourceMgr* resMgr = session->resourceMgr();
+
+      Standard_Real anXPos = resMgr->doubleValue( "Geometry", "scalar_bar_x_position", 0.05 );
+      Standard_Real anYPos = resMgr->doubleValue( "Geometry", "scalar_bar_y_position", 0.1 );
+      Standard_Real aWidth = resMgr->doubleValue( "Geometry", "scalar_bar_width", 0.2 );
+      Standard_Real aHeight = resMgr->doubleValue( "Geometry", "scalar_bar_height", 0.5 );
+      Standard_Integer aTextHeight = resMgr->integerValue( "Geometry", "scalar_bar_text_height", 14 );
+      Standard_Integer aNbIntervals = resMgr->integerValue( "Geometry", "scalar_bar_nb_intervals", 20 );
+      aColorScale->SetXPosition( anXPos );
+      aColorScale->SetYPosition( anYPos );
+      aColorScale->SetWidth( aWidth );
+      aColorScale->SetHeight( aHeight );
+
+      aColorScale->SetTextHeight( aTextHeight );
+      aColorScale->SetNumberOfIntervals( anIsBoolean ? 2 : aNbIntervals );
+
+      aColorScale->SetTitle( aColorScaleTitle );
+      aColorScale->SetRange( aColorScaleMin, aColorScaleMax );
+    }
+    if( !aView->ColorScaleIsDisplayed() )
+      aView->ColorScaleDisplay();
+  }
+  else
+  {
+    if( aView->ColorScaleIsDisplayed() )
+      aView->ColorScaleErase();
+  }
+
+  if( theIsRedisplayFieldSteps )
+  {
+    _PTR(Study) aStudyDS = aStudy->studyDS();
+    QList<SUIT_ViewManager*> vmList;
+    myApp->viewManagers( vmList );
+    for( QList<SUIT_ViewManager*>::Iterator vmIt = vmList.begin(); vmIt != vmList.end(); vmIt++ )
+    {
+      if( SUIT_ViewManager* aViewManager = *vmIt )
+      {
+        const ObjMap anObjects = aStudy->getObjectMap( aViewManager->getGlobalId() );
+        for( ObjMap::ConstIterator objIt = anObjects.begin(); objIt != anObjects.end(); objIt++ )
+        {
+          _PTR(SObject) aSObj( aStudyDS->FindObjectID( objIt.key().toLatin1().constData() ) );
+          if( aSObj )
+          {
+            CORBA::Object_var anObject = GeometryGUI::ClientSObjectToObject( aSObj );
+            if( !CORBA::is_nil( anObject ) )
+            {
+              GEOM::GEOM_FieldStep_var aFieldStep = GEOM::GEOM_FieldStep::_narrow( anObject );
+              if( !aFieldStep->_is_nil() )
+              {
+                CORBA::String_var aStepEntry = aFieldStep->GetStudyEntry();
+                Handle(SALOME_InteractiveObject) aStepIO =
+                  new SALOME_InteractiveObject( aStepEntry.in(), "GEOM", "TEMP_IO" );
+                Redisplay( aStepIO, false, false );
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  UpdateViewer();
+}
index 4f0c137f4994aea24594bdd03b710e0f82e9bac7..e5ee15cec857aa0ec20d159e01dd4fcf1e302eb8 100644 (file)
@@ -44,6 +44,7 @@ class SALOME_OCCViewType;
 #include <LightApp_Displayer.h>
 #include <LightApp_Study.h>
 #include <Aspect_TypeOfMarker.hxx>
+#include <TCollection_AsciiString.hxx>
 
 #include <QList>
 
@@ -85,18 +86,19 @@ public:
 
   // This overloaded Display() method can be useful for operations
   // not using dialog boxes.
-  void          Display   ( GEOM::GEOM_Object_ptr theObj,
+  void          Display   ( GEOM::GEOM_BaseObject_ptr theObj,
                             const bool updateViewer = true );
 
   void          Redisplay ( const Handle(SALOME_InteractiveObject)& theIO,
-                            const bool updateViewer = true );
+                            const bool updateViewer = true,
+                            const bool checkActiveViewer = true );
 
   void          Erase     ( const Handle(SALOME_InteractiveObject)& theIO,
                             const bool forced = false,
                             const bool updateViewer = true,
                             SALOME_View* theViewFrame = 0 );
 
-  void          Erase     ( GEOM::GEOM_Object_ptr theObj,
+  void          Erase     ( GEOM::GEOM_BaseObject_ptr theObj,
                             const bool forced = false,
                             const bool updateViewer = true );
 
@@ -113,7 +115,8 @@ public:
                             const bool updateViewer = true );
 
   void          Redisplay ( const SALOME_ListIO& theIOList,
-                            const bool updateViewer = true );
+                            const bool updateViewer = true,
+                            const bool checkActiveViewer = true );
 
   /* build presentation accordint to the current viewer type*/
   SALOME_Prs*   BuildPrs  ( GEOM::GEOM_Object_ptr );
@@ -157,6 +160,7 @@ public:
   virtual void  Update( SALOME_VTKPrs* );
   virtual void  BeforeDisplay( SALOME_View*, const SALOME_OCCPrs* );
   virtual void  AfterDisplay ( SALOME_View*, const SALOME_OCCPrs* );
+  virtual void  AfterErase   ( SALOME_View*, const SALOME_OCCPrs* );
 
   /* This methos is used for activisation/deactivisation of objects to be displayed*/
   void          SetToActivate( const bool );
@@ -188,6 +192,9 @@ public:
                                                 const QString&,
                                                 SALOME_View* = 0);
 
+  /* Update visibility and parameters of the currently selected field step's color scale */
+  void UpdateColorScale( const bool theIsRedisplayFieldSteps = false );
+
 protected:
   /* internal methods */
   /* Builds presentation according to the current viewer type */
@@ -199,6 +206,14 @@ protected:
   /* Sets shape */
   void        setShape( const TopoDS_Shape& theShape );
 
+  /* Sets field step information */
+  void        setFieldStepInfo( const GEOM::field_data_type theFieldDataType,
+                                const int theFieldDimension,
+                                const QList<QVariant>& theFieldStepData,
+                                const TCollection_AsciiString& theFieldStepName,
+                                const double theFieldStepRangeMin,
+                                const double theFieldStepRangeMax );
+
   /* Resets internal data */
   void        internalReset();
 
@@ -214,10 +229,36 @@ protected:
 
   PropMap getObjectProperties( SalomeApp_Study*, const QString&, SALOME_View* = 0 );
   PropMap getDefaultPropertyMap();
-  
+
+  /* Methods for reading the field step information */
+  void            readFieldStepInfo( GEOM::GEOM_FieldStep_var theGeomFieldStep );
+  QList<QVariant> groupFieldData( const QList<QVariant>& theFieldStepData,
+                                  const int theFieldNbComponents,
+                                  const bool theIsString,
+                                  double& theFieldStepRangeMin,
+                                  double& theFieldStepRangeMax );
+
+  // Note: the method is copied from Aspect_ColorScale class
+  static Standard_Integer HueFromValue( const Standard_Integer aValue,
+                                        const Standard_Integer aMin,
+                                        const Standard_Integer aMax );
+
+  // Note: the method is copied from Aspect_ColorScale class
+  static Standard_Boolean FindColor( const Standard_Real aValue, 
+                                     const Standard_Real aMin,
+                                     const Standard_Real aMax,
+                                     const Standard_Integer ColorsCount,
+                                     Quantity_Color& aColor );
+
 protected:
   Handle(SALOME_InteractiveObject) myIO;
   TopoDS_Shape                     myShape;
+  GEOM::field_data_type            myFieldDataType;
+  int                              myFieldDimension;
+  QList<QVariant>                  myFieldStepData;
+  TCollection_AsciiString          myFieldStepName;
+  double                           myFieldStepRangeMin;
+  double                           myFieldStepRangeMax;
   std::string                      myName;
   std::string                      myTexture;
   int                              myType;
index 8fb6812034cb4641c1148f249fd7bee5eda886d9..c0b8d2e951fa54510064cbe64edf82b5ff8eb003 100644 (file)
@@ -3232,6 +3232,35 @@ Please, select face, shell or solid and try again</translation>
         <source>PREF_ISOS_V</source>
         <translation>Along V</translation>
     </message>
+    <message>
+        <source>PREF_GROUP_SCALAR_BAR</source>
+        <translation>Scalar bar for field step presentation</translation>
+    </message>
+    <message>
+        <source>PREF_SCALAR_BAR_X_POSITION</source>
+        <translation>X position</translation>
+    </message>
+    <message>
+        <source>PREF_SCALAR_BAR_Y_POSITION</source>
+        <translation>Y position</translation>
+    </message>
+    <message>
+        <source>PREF_SCALAR_BAR_WIDTH</source>
+        <translation>Width</translation>
+    </message>
+    <message>
+        <source>PREF_SCALAR_BAR_HEIGHT</source>
+        <translation>Height</translation>
+    </message>
+    <message>
+        <source>PREF_SCALAR_BAR_TEXT_HEIGHT</source>
+        <translation>Text height</translation>
+    </message>
+    <message>
+        <source>PREF_SCALAR_BAR_NUMBER_OF_INTERVALS</source>
+        <translation>Number of intervals</translation>
+    </message>
+
     <message>
         <source>PROCESS_SHAPE_NEW_OBJ_NAME</source>
         <translation>ProcessShape</translation>
index 2e88829e7779a47822a2a65153ecc9720cbbf54d..df17cd48452492c14a9ed3998536de25a6aea16b 100644 (file)
@@ -1773,6 +1773,7 @@ bool GeometryGUI::activateModule( SUIT_Study* study )
 
   connect( sm, SIGNAL( currentSelectionChanged() ), this, SLOT( updateCreationInfo() ));
   connect( sm, SIGNAL( currentSelectionChanged() ), this, SLOT( onAutoBringToFront() ));
+  connect( sm, SIGNAL( currentSelectionChanged() ), this, SLOT( updateFieldColorScale() ));
 
   if ( !myCreationInfoWdg )
     myCreationInfoWdg = new GEOMGUI_CreationInfoWdg( getApp() );
@@ -1853,6 +1854,7 @@ bool GeometryGUI::deactivateModule( SUIT_Study* study )
   LightApp_SelectionMgr* selMrg = getApp()->selectionMgr();
 
   disconnect( selMrg, SIGNAL( currentSelectionChanged() ), this, SLOT( updateCreationInfo() ));
+  disconnect( selMrg, SIGNAL( currentSelectionChanged() ), this, SLOT( updateFieldColorScale() ));
   getApp()->removeDockWindow( myCreationInfoWdg->getWinID() );
   myCreationInfoWdg = 0;
 
@@ -2104,6 +2106,15 @@ void GeometryGUI::onAutoBringToFront()
   GeometryGUI::Modified();
 }
 
+void GeometryGUI::updateFieldColorScale()
+{
+  if( SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApp()->activeStudy() ) )
+  {
+    GEOM_Displayer aDisplayer( aStudy );
+    aDisplayer.UpdateColorScale();
+  }
+}
+
 QString GeometryGUI::engineIOR() const
 {
   if ( !CORBA::is_nil( GetGeomGen() ) )
@@ -2436,6 +2447,46 @@ void GeometryGUI::createPreferences()
   setPreferenceProperty( markerScale, "strings", aMarkerScaleValuesList );
   setPreferenceProperty( markerScale, "indexes", aMarkerScaleIndicesList );
 
+  // Scalar bar for field step presentation
+  int scalarBarGroup = addPreference( tr( "PREF_GROUP_SCALAR_BAR" ), tabId );
+  setPreferenceProperty( scalarBarGroup, "columns", 2 );
+
+  int sbXPosition = addPreference( tr( "PREF_SCALAR_BAR_X_POSITION" ), scalarBarGroup,
+                                   LightApp_Preferences::DblSpin, "Geometry", "scalar_bar_x_position" );
+  setPreferenceProperty( sbXPosition, "min", 0 );
+  setPreferenceProperty( sbXPosition, "max", 1 );
+  setPreferenceProperty( sbXPosition, "step", 0.05 );
+
+  int sbYPosition = addPreference( tr( "PREF_SCALAR_BAR_Y_POSITION" ), scalarBarGroup,
+                                   LightApp_Preferences::DblSpin, "Geometry", "scalar_bar_y_position" );
+  setPreferenceProperty( sbYPosition, "min", 0 );
+  setPreferenceProperty( sbYPosition, "max", 1 );
+  setPreferenceProperty( sbYPosition, "step", 0.05 );
+
+  int sbWidth = addPreference( tr( "PREF_SCALAR_BAR_WIDTH" ), scalarBarGroup,
+                               LightApp_Preferences::DblSpin, "Geometry", "scalar_bar_width" );
+  setPreferenceProperty( sbWidth, "min", 0 );
+  setPreferenceProperty( sbWidth, "max", 1 );
+  setPreferenceProperty( sbWidth, "step", 0.05 );
+
+  int sbHeight = addPreference( tr( "PREF_SCALAR_BAR_HEIGHT" ), scalarBarGroup,
+                                LightApp_Preferences::DblSpin, "Geometry", "scalar_bar_height" );
+  setPreferenceProperty( sbHeight, "min", 0 );
+  setPreferenceProperty( sbHeight, "max", 1 );
+  setPreferenceProperty( sbHeight, "step", 0.05 );
+
+  int sbTextHeight = addPreference( tr( "PREF_SCALAR_BAR_TEXT_HEIGHT" ), scalarBarGroup,
+                                    LightApp_Preferences::IntSpin, "Geometry", "scalar_bar_text_height" );
+  setPreferenceProperty( sbTextHeight, "min", 6 );
+  setPreferenceProperty( sbTextHeight, "max", 24 );
+  setPreferenceProperty( sbTextHeight, "step", 1 );
+
+  int sbNbIntervals = addPreference( tr( "PREF_SCALAR_BAR_NUMBER_OF_INTERVALS" ), scalarBarGroup,
+                                     LightApp_Preferences::IntSpin, "Geometry", "scalar_bar_nb_intervals" );
+  setPreferenceProperty( sbNbIntervals, "min", 2 );
+  setPreferenceProperty( sbNbIntervals, "max", 64 );
+  setPreferenceProperty( sbNbIntervals, "step", 1 );
+
   int originGroup = addPreference( tr( "PREF_GROUP_ORIGIN_AND_BASE_VECTORS" ), tabId );
   setPreferenceProperty( originGroup, "columns", 2 );
 
@@ -2469,6 +2520,19 @@ void GeometryGUI::preferencesChanged( const QString& section, const QString& par
     else if (param == QString("toplevel_dm")) {
       GEOM_AISShape::setTopLevelDisplayMode((GEOM_AISShape::TopLevelDispMode)aResourceMgr->integerValue("Geometry", "toplevel_dm", 0));
     }
+    else if (param == QString("scalar_bar_x_position") ||
+             param == QString("scalar_bar_y_position") ||
+             param == QString("scalar_bar_width") ||
+             param == QString("scalar_bar_height") ||
+             param == QString("scalar_bar_text_height") ||
+             param == QString("scalar_bar_nb_intervals")) {
+      if( SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApp()->activeStudy() ) )
+      {
+        GEOM_Displayer aDisplayer( aStudy );
+        bool anIsRedisplayFieldSteps = param == QString("scalar_bar_nb_intervals");
+        aDisplayer.UpdateColorScale( anIsRedisplayFieldSteps );
+      }
+    }
   }
 }
 
index 78eb05db4845c69ff027678909ec1d5f023febc7..3d4af608b70425bf0e4d7464939e6f41cb2794d8 100644 (file)
@@ -174,6 +174,7 @@ private slots:
   void                        updateMaterials();
   void                        updateCreationInfo();
   void                        onAutoBringToFront();
+  void                        updateFieldColorScale();
 
 signals :
   void                        SignalDeactivateActiveDialog();
index ed3d535e0e846bafd6f4806a74cc1043f1fa7217..e634e8c90be0a42836915aba4855f0aa09c615b4 100644 (file)
@@ -47,6 +47,8 @@
 #include <gp_Vec.hxx>
 #include <Graphic3d_AspectFillArea3d.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
+#include <Graphic3d_AspectMarker3d.hxx>
+#include <Graphic3d_AspectText3d.hxx>
 
 #include <Prs3d_ShadingAspect.hxx>
 #include <Prs3d_Arrow.hxx>
@@ -58,6 +60,7 @@
 #include <SelectMgr_IndexedMapOfOwner.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <StdSelect_DisplayMode.hxx>
+#include <StdPrs_ShadedShape.hxx>
 #include <StdPrs_WFDeflectionShape.hxx>
 
 #include <TColStd_IndexedMapOfInteger.hxx>
@@ -142,8 +145,16 @@ static void indicesToOwners( const TColStd_IndexedMapOfInteger& aIndexMap,
 
 GEOM_AISShape::GEOM_AISShape(const TopoDS_Shape& shape,
                              const Standard_CString aName)
-  : SALOME_AISShape(shape), myName(aName), myDisplayVectors(false)
+  : SALOME_AISShape(shape),
+    myName(aName),
+    myDisplayVectors(false),
+    myFieldDataType(GEOM::FDT_Double),
+    myFieldDimension(0),
+    myFieldStepRangeMin(0),
+    myFieldStepRangeMax(0)
 {
+  SetHilightMode( CustomHighlight ); // override setting the mode to 0 inside AIS_Shape constructor
+
   myShadingColor = Quantity_Color( Quantity_NOC_GOLDENROD );
   myPrevDisplayMode = 0;
   storeBoundaryColors();
@@ -203,11 +214,16 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
   if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //pas de prise en compte lors du FITALL
 
   Handle(AIS_InteractiveContext) anIC = GetContext();
+
+  bool anIsField = !myFieldStepData.isEmpty();
+  bool anIsColorField = anIsField && myFieldDataType != GEOM::FDT_String;
+  bool anIsTextField = anIsField && myFieldDataType == GEOM::FDT_String;
+
   //   StdSelect_DisplayMode d = (StdSelect_DisplayMode) aMode;
   bool isTopLev = isTopLevel() && switchTopLevel();
   switch (aMode) {
     case 0://StdSelect_DM_Wireframe: 
+    case CustomHighlight:
     {
       restoreIsoNumbers();
       // Restore wireframe edges colors
@@ -218,7 +234,10 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
               anAspect->SetColor( topLevelColor() );
               Attributes()->SetWireAspect( anAspect );
       }
-     StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);      
+      if( !isTopLev && anIsColorField && myFieldDimension == 1 )
+        drawField( aPrs, false, aMode == CustomHighlight );
+      else
+        StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);      
       break;
     }
     case 1://StdSelect_DM_Shading:
@@ -264,7 +283,10 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
     myDrawer->SetFreeBoundaryAspect( anAspect );
 
     // Add edges to presentation
-    StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
+    if( anIsColorField && myFieldDimension == 1 )
+      drawField( aPrs );
+    else
+      StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
   }
 
   if (isShowVectors())
@@ -312,6 +334,15 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent
       }
     }
   }
+
+  // draw color field on vertices
+  if( anIsColorField && myFieldDimension == 0 && aMode != CustomHighlight )
+    drawField( aPrs );
+
+  // draw text field
+  if( anIsTextField )
+    drawField( aPrs, true );
+
   //  aPrs->ReCompute(); // for hidden line recomputation if necessary...
 }
 
@@ -383,9 +414,17 @@ void GEOM_AISShape::shadingMode(const Handle(PrsMgr_PresentationManager3d)& aPre
       myDrawer->ShadingAspect()->SetColor(myDrawer->ShadingAspect()->Aspect()->FrontMaterial().AmbientColor());
   }
 
-  // PAL12113: AIS_Shape::Compute() works correctly with shapes containing no faces
-  //StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
-  AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
+  bool anIsColorField = !myFieldStepData.isEmpty() && myFieldDataType != GEOM::FDT_String;
+  if( anIsColorField && ( myFieldDimension == 2 || myFieldDimension == 3 || myFieldDimension == -1 ) )
+  {
+    drawField( aPrs );
+  }
+  else
+  {
+    // PAL12113: AIS_Shape::Compute() works correctly with shapes containing no faces
+    //StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
+    AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
+  }
 }
 
 void GEOM_AISShape::storeIsoNumbers()
@@ -492,3 +531,170 @@ Standard_Boolean GEOM_AISShape::switchTopLevel() {
 Standard_Boolean GEOM_AISShape::toActivate() {
         return Standard_True;
 }
+
+void GEOM_AISShape::setFieldStepInfo( const GEOM::field_data_type theFieldDataType,
+                                      const int theFieldDimension,
+                                      const QList<QVariant>& theFieldStepData,
+                                      const TCollection_AsciiString& theFieldStepName,
+                                      const double theFieldStepRangeMin,
+                                      const double theFieldStepRangeMax )
+{
+  myFieldDataType = theFieldDataType;
+  myFieldDimension = theFieldDimension;
+  myFieldStepData = theFieldStepData;
+  myFieldStepName = theFieldStepName;
+  myFieldStepRangeMin = theFieldStepRangeMin;
+  myFieldStepRangeMax = theFieldStepRangeMax;
+}
+
+void GEOM_AISShape::getFieldStepInfo( GEOM::field_data_type& theFieldDataType,
+                                      int& theFieldDimension,
+                                      QList<QVariant>& theFieldStepData,
+                                      TCollection_AsciiString& theFieldStepName,
+                                      double& theFieldStepRangeMin,
+                                      double& theFieldStepRangeMax ) const
+{
+  theFieldDataType = myFieldDataType;
+  theFieldDimension = myFieldDimension;
+  theFieldStepData = myFieldStepData;
+  theFieldStepName = myFieldStepName;
+  theFieldStepRangeMin = myFieldStepRangeMin;
+  theFieldStepRangeMax = myFieldStepRangeMax;
+}
+
+void GEOM_AISShape::drawField( const Handle(Prs3d_Presentation)& thePrs,
+                               const bool theIsString,
+                               const bool theIsHighlight )
+{
+  if( myFieldStepData.isEmpty() )
+    return;
+
+  QListIterator<QVariant> aFieldStepDataIter( myFieldStepData );
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
+  switch( myFieldDimension )
+  {
+    case 0: aShapeType = TopAbs_VERTEX; break;
+    case 1: aShapeType = TopAbs_EDGE; break;
+    case 2: aShapeType = TopAbs_FACE; break;
+    case 3: aShapeType = TopAbs_SOLID; break;
+    case -1: aShapeType = TopAbs_VERTEX; break;
+  }
+
+  TopTools_IndexedMapOfShape aShapeMap;
+  TopExp::MapShapes( myshape, aShapeMap );
+
+  TColStd_IndexedMapOfInteger anIndexMap;
+
+  TopExp_Explorer anExp;
+  for( anExp.Init( myshape, aShapeType ); anExp.More(); anExp.Next() )
+  {
+    TopoDS_Shape aSubShape = anExp.Current();
+    if( !aSubShape.IsNull() )
+    {
+      Standard_Integer aSubShapeIndex = aShapeMap.FindIndex( aSubShape );
+      if( anIndexMap.Contains( aSubShapeIndex ) )
+        continue;
+
+      anIndexMap.Add( aSubShapeIndex );
+
+      Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup( thePrs );
+
+      QColor aQColor;
+      QString aString;
+      if( aFieldStepDataIter.hasNext() )
+      {
+        const QVariant& aVariant = aFieldStepDataIter.next();
+        if( theIsString )
+          aString = aVariant.toString();
+        else
+          aQColor = aVariant.value<QColor>();
+      }
+      else
+        break;
+
+      if( theIsString )
+      {
+        gp_Pnt aCenter;
+        if( computeMassCenter( aSubShape, aCenter ) )
+        {
+          Graphic3d_Vertex aVertex( aCenter.X(), aCenter.Y(), aCenter.Z() );
+
+          Handle(Graphic3d_AspectText3d) anAspectText3d = new Graphic3d_AspectText3d();
+          anAspectText3d->SetStyle( Aspect_TOST_ANNOTATION );
+          aGroup->SetPrimitivesAspect( anAspectText3d );
+
+          aGroup->Text( aString.toLatin1().constData(), aVertex, 14 );
+        }
+      }
+      else
+      {
+        Quantity_Color aColor( aQColor.redF(), aQColor.greenF(), aQColor.blueF(), Quantity_TOC_RGB );
+        if( myFieldDimension == 0 )
+        {
+          TopoDS_Vertex aVertexShape = TopoDS::Vertex( aSubShape );
+          if( !aVertexShape.IsNull() )
+          {
+            gp_Pnt aPnt = BRep_Tool::Pnt( aVertexShape );
+
+            Handle(Graphic3d_AspectMarker3d) anAspectMarker3d = new Graphic3d_AspectMarker3d();
+            anAspectMarker3d->SetColor( aColor );
+            anAspectMarker3d->SetType( Aspect_TOM_POINT );
+            anAspectMarker3d->SetScale( 10.0 );
+            aGroup->SetPrimitivesAspect( anAspectMarker3d );
+
+            Handle(Graphic3d_ArrayOfPoints) anArray = new Graphic3d_ArrayOfPoints( 1 );
+            anArray->AddVertex( aPnt.X(), aPnt.Y(), aPnt.Z() );
+
+            aGroup->AddPrimitiveArray( anArray );
+          }
+        }
+        else if( myFieldDimension == 1 )
+        {
+          myDrawer->WireAspect()->SetColor( aColor );
+          if( theIsHighlight )
+            myDrawer->WireAspect()->SetWidth( myOwnWidth );
+          else
+            myDrawer->WireAspect()->SetWidth( myOwnWidth + 4 );
+          StdPrs_WFDeflectionShape::Add( thePrs, aSubShape, myDrawer );
+        }
+        else if( myFieldDimension == 2 ||
+                 myFieldDimension == 3 ||
+                 myFieldDimension == -1 )
+        {
+          myDrawer->ShadingAspect()->SetColor( aColor );
+          StdPrs_ShadedShape::Add( thePrs, aSubShape, myDrawer );
+        }
+      }
+    }
+  }
+}
+
+Standard_Boolean GEOM_AISShape::computeMassCenter( const TopoDS_Shape& theShape,
+                                                   gp_Pnt& theCenter )
+{
+  Standard_Real aX = 0, aY = 0, aZ = 0;
+  Standard_Integer aNbPoints = 0;
+
+  TopExp_Explorer anExp;
+  for( anExp.Init( theShape, TopAbs_VERTEX ); anExp.More(); anExp.Next() )
+  {
+    TopoDS_Vertex aVertex = TopoDS::Vertex( anExp.Current() );
+    if( !aVertex.IsNull() )
+    {
+      gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
+      aX += aPnt.X();
+      aY += aPnt.Y();
+      aZ += aPnt.Z();
+      aNbPoints++;
+    }
+  }
+
+  if( aNbPoints == 0 )
+    return Standard_False;
+
+  theCenter.SetCoord( aX / (Standard_Real)aNbPoints,
+                      aY / (Standard_Real)aNbPoints,
+                      aZ / (Standard_Real)aNbPoints );
+  return Standard_True;
+}
index db0fe617684d39a4b7653b13def9a54a2dcbd3dc..3a61cfed304d47f0a0280bcc74605f194295ca2c 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "GEOM_OBJECT_defs.hxx"
 
+#include <GEOM_Gen.hh>
+
 #ifndef _Standard_HeaderFile
 #include <Standard.hxx>
 #endif
@@ -60,6 +62,9 @@
 #include <AIS_DisplayMode.hxx>
 #include <Graphic3d_MaterialAspect.hxx>
 
+#include <QList>
+#include <QVariant>
+
 class PrsMgr_PresentationManager3d;
 class Prs3d_Presentation;
 class SALOME_InteractiveObject;
@@ -74,7 +79,8 @@ public:
       //WireFrame,       //!< the same as AIS_WireFrame
       //Shading,         //!< the same as AIS_Shaded
       ShadingWithEdges = AIS_Shaded+1, //!< shading with edges
-      TexturedShape = ShadingWithEdges+1 //!< the same as AIS_ExactHLR
+      TexturedShape = ShadingWithEdges+1, //!< the same as AIS_ExactHLR
+      CustomHighlight = TexturedShape+1
     } DispMode;
 
     //! Enumeration of top level display modes
@@ -149,6 +155,19 @@ public:
   void setPrevDisplayMode(const Standard_Integer mode);
   Standard_Integer prevDisplayMode() const {return myPrevDisplayMode;}
 
+  // Field step information
+  void setFieldStepInfo( const GEOM::field_data_type theFieldDataType,
+                         const int theFieldDimension,
+                         const QList<QVariant>& theFieldStepData,
+                         const TCollection_AsciiString& theFieldStepName,
+                         const double theFieldStepRangeMin,
+                         const double theFieldStepRangeMax );
+  void getFieldStepInfo( GEOM::field_data_type& theFieldDataType,
+                         int& theFieldDimension,
+                         QList<QVariant>& theFieldStepData,
+                         TCollection_AsciiString& theFieldStepName,
+                         double& theFieldStepRangeMin,
+                         double& theFieldStepRangeMax ) const;
 
 protected: 
   void shadingMode(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
@@ -157,6 +176,15 @@ protected:
 
   void restoreBoundaryColors();
 
+  // Displaying the field data
+  void drawField( const Handle(Prs3d_Presentation)& thePrs,
+                  const bool theIsText = false,
+                  const bool theIsHighlight = false );
+
+  // Auxiliary method to compute a center of mass for the specified shape
+  static Standard_Boolean computeMassCenter( const TopoDS_Shape& theShape,
+                                             gp_Pnt& theCenter );
+
   Quantity_Color myShadingColor;
 
   Quantity_Color myFreeBoundaryColor;
@@ -173,6 +201,13 @@ private:
   Standard_Boolean         myTopLevel;
   Standard_Integer         myPrevDisplayMode;
 
+  GEOM::field_data_type    myFieldDataType;
+  int                      myFieldDimension;
+  QList<QVariant>          myFieldStepData;
+  TCollection_AsciiString  myFieldStepName;
+  double                   myFieldStepRangeMin;
+  double                   myFieldStepRangeMax;
+
   static TopLevelDispMode myTopLevelDm;
   static Quantity_Color   myTopLevelColor;
 };