Salome HOME
moved method imageToPixmap() from GEOM_Displayer to GUI module (OCCViewer) as external
[modules/geom.git] / src / GEOMGUI / GEOM_Displayer.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : GEOM_Displayer.cxx
25 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26
27 #include "GEOM_Displayer.h"
28 #include "GEOMGUI_DimensionProperty.h"
29 #include "GeometryGUI.h"
30
31 #include <GEOM_Constants.h>
32 #include <GEOM_TypeFilter.h>
33 #include <GEOM_EdgeFilter.h>
34 #include <GEOM_FaceFilter.h>
35 #include <GEOM_CompoundFilter.h>
36 #include <GEOM_PreviewFilter.h>
37 #include <GEOM_LogicalFilter.h>
38 #include <GEOM_OCCFilter.h>
39
40 #include <GEOM_Actor.h>
41 #include <GEOM_AISShape.hxx>
42 #include <GEOM_AISDimension.hxx>
43 #include <GEOM_TopWireframeShape.hxx>
44 #include <GEOM_AISVector.hxx>
45 #include <GEOM_AISTrihedron.hxx>
46 #include <GEOM_VTKTrihedron.hxx>
47 #include <GEOM_VTKPropertyMaterial.hxx>
48
49 #include <GEOMUtils.hxx>
50
51 #include <Material_Model.h>
52
53 #include <SUIT_Desktop.h>
54 #include <SUIT_ViewWindow.h>
55 #include <SUIT_Session.h>
56 #include <SUIT_ViewManager.h>
57 #include <SUIT_ResourceMgr.h>
58
59 #include <Basics_OCCTVersion.hxx>
60
61 #include <SalomeApp_Study.h>
62 #include <SalomeApp_Application.h>
63 #include <LightApp_SelectionMgr.h>
64 #include <LightApp_DataObject.h>
65 #include <SalomeApp_TypeFilter.h>
66 #include <SalomeApp_Tools.h>
67
68 #include <SALOME_ListIteratorOfListIO.hxx>
69 #include <SALOME_ListIO.hxx>
70 #include <SALOME_Prs.h>
71
72 #include <SOCC_Prs.h>
73 #include <SOCC_ViewModel.h>
74
75 #include <SVTK_Prs.h>
76 #include <SVTK_ViewModel.h>
77
78 #include <OCCViewer_ViewWindow.h>
79 #include <OCCViewer_ViewPort3d.h>
80 #include <OCCViewer_Utilities.h>
81
82 // OCCT Includes
83 #include <AIS_Drawer.hxx>
84 #include <AIS_Dimension.hxx>
85 #include <AIS_LengthDimension.hxx>
86 #include <AIS_DiameterDimension.hxx>
87 #include <AIS_AngleDimension.hxx>
88 #include <AIS_ListIteratorOfListOfInteractive.hxx>
89 #include <Aspect_PolygonOffsetMode.hxx>
90 #include <Aspect_ColorScale.hxx>
91 #include <Prs3d_IsoAspect.hxx>
92 #include <Prs3d_PointAspect.hxx>
93 #include <StdSelect_TypeOfEdge.hxx>
94 #include <StdSelect_TypeOfFace.hxx>
95 #include <StdSelect_DisplayMode.hxx>
96 #include <TopoDS_Face.hxx>
97 #include <BRep_Tool.hxx>
98 #include <Geom_Plane.hxx>
99 #include <Geom_Axis2Placement.hxx>
100 #include <Graphic3d_AspectFillArea3d.hxx>
101 #include <gp_Pln.hxx>
102 #include <TColStd_MapOfInteger.hxx>
103 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
104 #include <TopoDS_Iterator.hxx>
105 #include <Graphic3d_AspectMarker3d.hxx>
106 #include <TopTools_MapOfShape.hxx>
107 #include <TopTools_ListOfShape.hxx>
108 #include <TopTools_ListIteratorOfListOfShape.hxx>
109 #include <TopoDS.hxx>
110 #include <NCollection_DataMap.hxx>
111 #include <NCollection_Map.hxx>
112
113 #include <Prs3d_ShadingAspect.hxx>
114
115 #include <BRepMesh_IncrementalMesh.hxx>
116
117 // VTK Includes
118 #include <vtkActorCollection.h>
119 #include <vtkProperty.h>
120
121 // CORBA Headers
122 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
123
124 #include <GEOMImpl_Types.hxx>
125
126 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
127 #include <TColStd_HArray1OfByte.hxx>
128 #else
129 #include <Graphic3d_HArray1OfBytes.hxx>
130 #endif
131
132 // If the next macro is defined, autocolor feature works for all sub-shapes;
133 // if it is undefined, autocolor feature works for groups only
134 #define GENERAL_AUTOCOLOR
135 // Below macro, when uncommented, switches on simplified (more performant) algorithm
136 // of auto-color picking up
137 #define SIMPLE_AUTOCOLOR
138
139 // Hard-coded value of shape deflection coefficient for VTK viewer
140 const double VTK_MIN_DEFLECTION = 0.001;
141
142 #if OCC_VERSION_LARGE > 0x06070000
143 // Pixmap caching support
144 namespace
145 {
146   typedef NCollection_Map<Handle(GEOM_AISShape)>                    SetOfAISShapes;
147   typedef NCollection_DataMap<Handle(Image_PixMap), SetOfAISShapes> PixmapUsageMap;
148   typedef QMap<QString, Handle(Image_PixMap)>                       PixmapCacheMap;
149
150   static inline PixmapUsageMap& getPixmapUsageMap()
151   {
152     static PixmapUsageMap aMap;
153     return aMap;
154   }
155
156   static inline PixmapCacheMap& getPixmapCacheMap()
157   {
158     static PixmapCacheMap aMap;
159     return aMap;
160   }
161
162   //===========================================================================
163   // Function : getDefaultTexture
164   // Purpose  : Get default texture
165   //===========================================================================
166   static inline Handle(Image_PixMap) getDefaultTexture()
167   {
168     static Handle(Image_PixMap) aPixmap;
169     if ( aPixmap.IsNull() ) {
170       QPixmap px(":images/default_texture.png");
171       if ( !px.isNull() )
172         aPixmap = imageToPixmap( px.toImage() );
173     }
174     return aPixmap;
175   }
176
177   //===========================================================================
178   // Function : cacheTextureFor
179   // Purpose  : Load and cache image for the specified presentation.
180   //===========================================================================
181   static inline Handle(Image_PixMap) cacheTextureFor( const QString& thePath,
182                                                       const Handle(GEOM_AISShape)& theShape )
183   {
184     if ( thePath.isEmpty() )
185       return NULL;
186
187     PixmapUsageMap& aPixmapUsersMap = getPixmapUsageMap();
188     PixmapCacheMap& aPixmapCacheMap = getPixmapCacheMap();
189
190     Handle(Image_PixMap) aPixmap = aPixmapCacheMap.value( thePath, NULL );
191     if ( !aPixmap.IsNull() ) {
192       // point that the texture is used by the presentation
193       if ( !aPixmapUsersMap.IsBound( aPixmap ) )
194         aPixmapUsersMap.Bind( aPixmap, SetOfAISShapes() );
195
196       aPixmapUsersMap.ChangeFind( aPixmap ).Add( theShape );
197
198       return aPixmap;
199     }
200
201     // convert texture to compatible image format
202     QImage anImage = QImage( thePath ).convertToFormat( QImage::Format_ARGB32 );
203     if ( anImage.isNull() )
204       return NULL;
205
206     aPixmap = imageToPixmap( anImage );
207
208     aPixmapCacheMap.insert( thePath, aPixmap );
209
210     if ( !aPixmapUsersMap.IsBound( aPixmap ) )
211       aPixmapUsersMap.Bind( aPixmap, SetOfAISShapes() );
212
213     aPixmapUsersMap.ChangeFind( aPixmap ).Add( theShape );
214
215     return aPixmap;
216   }
217
218   //===========================================================================
219   // Function : releaseTextures
220   // Purpose  : Releases cached textures found for the specified presentation.
221   //===========================================================================
222   static inline void releaseTextures( const SALOME_OCCPrs* thePrs )
223   {
224     const SOCC_Prs* anOccPrs = dynamic_cast<const SOCC_Prs*>( thePrs );
225
226     AIS_ListOfInteractive aListOfIO;
227
228     anOccPrs->GetObjects( aListOfIO );
229
230     AIS_ListIteratorOfListOfInteractive aIterateIO( aListOfIO );
231
232     PixmapUsageMap& aPixmapUsersMap = getPixmapUsageMap();
233     PixmapCacheMap& aPixmapCacheMap = getPixmapCacheMap();
234
235     for ( ; aIterateIO.More(); aIterateIO.Next() )
236     {
237       Handle(GEOM_AISShape) aAISShape =
238         Handle(GEOM_AISShape)::DownCast( aIterateIO.Value() );
239
240       if ( aAISShape.IsNull() )
241         continue;
242
243       const Handle(Image_PixMap)& aPixmap = aAISShape->TexturePixMap();
244       if ( aPixmap.IsNull() )
245         continue;
246
247       if ( !aPixmapUsersMap.IsBound( aPixmap ) )
248         continue;
249
250       SetOfAISShapes& aUsersShapes = aPixmapUsersMap.ChangeFind( aPixmap );
251
252       aUsersShapes.Remove( aAISShape );
253
254       if ( aUsersShapes.IsEmpty() ) {
255         aPixmapUsersMap.UnBind( aPixmap );
256         aPixmapCacheMap.remove( aPixmapCacheMap.key( aPixmap ) );
257       }
258     }
259   }
260 }
261 #endif
262
263 //================================================================
264 // Function : getActiveStudy
265 // Purpose  : Get active study, returns 0 if no open study frame
266 //================================================================
267 static inline SalomeApp_Study* getActiveStudy()
268 {
269   SUIT_Session* session = SUIT_Session::session();
270   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
271   if ( app )
272     return ( SalomeApp_Study* )app->activeStudy();
273   return 0;
274 }
275
276 static inline int getViewManagerId( SALOME_View* theViewFrame) {
277   SUIT_ViewModel* aModel = dynamic_cast<SUIT_ViewModel*>(theViewFrame);
278   SUIT_ViewManager* aViewMgr = 0;
279   if (aModel != 0)
280     aViewMgr = aModel->getViewManager();
281   return ((aViewMgr == 0) ? -1 :aViewMgr->getGlobalId());
282 }
283
284 //================================================================
285 // Function : getTopAbsMode
286 // Purpose  : Get TopAbs_ShapeEnum value corresponding to the
287 //            one from GEOMImpl_Types.h
288 //================================================================
289 static inline int getTopAbsMode( const int implType )
290 {
291   switch ( implType )
292   {
293     case GEOM_COMPOUND  : return TopAbs_COMPOUND;
294     case GEOM_SOLID     : return TopAbs_SOLID;
295     case GEOM_SHELL     : return TopAbs_SHELL;
296     case GEOM_FACE      : return TopAbs_FACE;
297     case GEOM_WIRE      : return TopAbs_WIRE;
298     case GEOM_EDGE      : return TopAbs_EDGE;
299     case GEOM_POINT     : return TopAbs_VERTEX;
300     default             : return -1;
301   }
302 }
303
304 int GEOM_Displayer::getMinMaxShapeType( const TopoDS_Shape& shape, bool ismin )
305 {
306   if ( shape.IsNull() )
307     return TopAbs_SHAPE;
308
309   int ret = shape.ShapeType();
310
311   if ( shape.ShapeType() == TopAbs_COMPOUND || shape.ShapeType() == TopAbs_COMPSOLID ) {
312     TopoDS_Iterator it(shape, Standard_True, Standard_False);
313     for (; it.More(); it.Next()) {
314       TopoDS_Shape sub_shape = it.Value();
315       if ( sub_shape.IsNull() ) continue;
316       int stype = getMinMaxShapeType( sub_shape, ismin );
317       if ( stype == TopAbs_SHAPE ) continue;
318       if ( ismin && stype > ret )
319         ret = stype;
320       else if ( !ismin && ( ret < TopAbs_SOLID || stype < ret ) )
321         ret = stype;
322     }
323   }
324
325   return ret;
326 }
327
328 bool GEOM_Displayer::isCompoundOfVertices( const TopoDS_Shape& theShape )
329 {
330   return theShape.ShapeType() == TopAbs_COMPOUND && getMinMaxShapeType( theShape, false ) == TopAbs_VERTEX;
331 }
332
333 //================================================================
334 // Function : getFilter
335 // Purpose  : Get filter corresponding to the type of object
336 //            from GEOMImpl_Types.h
337 //================================================================
338 SUIT_SelectionFilter* GEOM_Displayer::getFilter( const int theMode )
339 {
340   SUIT_SelectionFilter* aFilter;
341
342   int aTopAbsMode = getTopAbsMode( theMode );
343   if ( aTopAbsMode != -1 )
344     aFilter = new GEOM_TypeFilter( getStudy(), aTopAbsMode, true ); //@ aFilter = new GEOM_TypeFilter( ( TopAbs_ShapeEnum )aTopAbsMode );
345   else
346     switch ( theMode )
347       {
348       case GEOM_LINE      : aFilter = new GEOM_EdgeFilter( getStudy(), StdSelect_Line ); break;
349       case GEOM_CIRCLE    : aFilter = new GEOM_EdgeFilter( getStudy(), StdSelect_Circle ); break;
350
351       case GEOM_PLANE     : aFilter = new GEOM_FaceFilter( getStudy(), StdSelect_Plane ); break;
352       case GEOM_CYLINDER  : aFilter = new GEOM_FaceFilter( getStudy(), StdSelect_Cylinder ); break;
353       case GEOM_SPHERE    : aFilter = new GEOM_FaceFilter( getStudy(), StdSelect_Sphere ); break;
354       case GEOM_TORUS     : aFilter = new GEOM_FaceFilter( getStudy(), StdSelect_Torus ); break;
355       case GEOM_REVOLUTION: aFilter = new GEOM_FaceFilter( getStudy(), StdSelect_Revol ); break;
356       case GEOM_CONE      : aFilter = new GEOM_FaceFilter( getStudy(), StdSelect_Cone ); break;
357
358       case GEOM_PREVIEW   : aFilter = new GEOM_PreviewFilter( getStudy() ); break;
359
360       case GEOM_ALLSHAPES : aFilter = new GEOM_SelectionFilter(getStudy(), true ); break;
361       case GEOM_ALLGEOM   : aFilter = new SalomeApp_TypeFilter( getStudy(), "GEOM" ); break;
362
363       default             : aFilter = new GEOM_TypeFilter( getStudy(), theMode ); break;
364       }
365
366   return aFilter;
367 }
368
369 //================================================================
370 // Function : getComplexFilter
371 // Purpose  : Get compound filter corresponding to the type of
372 //            object from GEOMImpl_Types.h
373 //================================================================
374 SUIT_SelectionFilter* GEOM_Displayer::getComplexFilter( const QList<int>* aSubShapes)
375 {
376   GEOM_CompoundFilter* aFilter;
377
378   if(aSubShapes != NULL ) {
379     aFilter = new GEOM_CompoundFilter(getStudy());
380     QList<int> aTopAbsTypes;
381     QList<int>::const_iterator it;
382     for(it = aSubShapes->constBegin(); it != aSubShapes->constEnd(); ++it ) {
383       int topAbsMode = getTopAbsMode(*it);
384       if(topAbsMode != -1 )
385         aTopAbsTypes.append(topAbsMode);
386     }
387     aFilter->addSubTypes(aTopAbsTypes);
388   }
389
390   return aFilter;
391 }
392
393 //================================================================
394 // Function : getEntry
395 // Purpose  :
396 //================================================================
397 static std::string getEntry( GEOM::GEOM_BaseObject_ptr object )
398 {
399   SUIT_Session* session = SUIT_Session::session();
400   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
401   if ( app )
402   {
403     CORBA::String_var IOR = app->orb()->object_to_string( object );
404     if ( strcmp(IOR.in(), "") != 0 )
405     {
406       SalomeApp_Study* study = ( SalomeApp_Study* )app->activeStudy();
407       _PTR(SObject) SO ( study->studyDS()->FindObjectIOR( std::string(IOR) ) );
408       if ( SO )
409         return SO->GetID();
410     }
411   }
412   return "";
413 }
414
415 //================================================================
416 // Function : getName
417 // Purpose  :
418 //================================================================
419 static std::string getName( GEOM::GEOM_BaseObject_ptr object )
420 {
421   SUIT_Session* session = SUIT_Session::session();
422   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
423   if ( app )
424   {
425     CORBA::String_var IOR = app->orb()->object_to_string( object );
426     if ( strcmp(IOR.in(), "") != 0 )
427     {
428       SalomeApp_Study* study = ( SalomeApp_Study* )app->activeStudy();
429       _PTR(SObject) aSObj ( study->studyDS()->FindObjectIOR( std::string(IOR) ) );
430
431       _PTR(GenericAttribute) anAttr;
432
433       if ( aSObj && aSObj->FindAttribute( anAttr, "AttributeName") )
434       {
435         _PTR(AttributeName) aNameAttr( anAttr );
436         return aNameAttr->Value();
437       }
438     }
439   }
440
441   return "";
442 }
443
444 //=================================================================
445 /*!
446  *  GEOM_Displayer::GEOM_Displayer
447  *  Constructor
448  */
449 //=================================================================
450 GEOM_Displayer::GEOM_Displayer( SalomeApp_Study* st )
451 {
452   if( st )
453     myApp = dynamic_cast<SalomeApp_Application*>( st->application() );
454   else
455     myApp = 0;
456
457   /* Shading Color */
458   SUIT_Session* session = SUIT_Session::session();
459   SUIT_ResourceMgr* resMgr = session->resourceMgr();
460
461   QColor col = resMgr->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) );
462   myShadingColor = SalomeApp_Tools::color( col );
463
464   myDisplayMode = resMgr->integerValue("Geometry", "display_mode", 0);
465   myHasDisplayMode = false;
466
467   int aType = resMgr->integerValue("Geometry", "type_of_marker", (int)Aspect_TOM_PLUS);
468   myWidth = resMgr->integerValue("Geometry", "edge_width", -1);
469   myIsosWidth = resMgr->integerValue("Geometry", "isolines_width", -1);
470   
471   myTransparency = resMgr->integerValue("Geometry", "transparency", 0) / 100.;
472   myHasTransparency = false;
473
474   myTypeOfMarker = (Aspect_TypeOfMarker)(std::min((int)Aspect_TOM_RING3, std::max((int)Aspect_TOM_POINT, aType)));
475   myScaleOfMarker = (resMgr->integerValue("Geometry", "marker_scale", 1)-(int)GEOM::MS_10)*0.5 + 1.0;
476   myScaleOfMarker = std::min(7.0, std::max(1., myScaleOfMarker));
477
478   myColor = -1;
479   // This color is used for shape displaying. If it is equal -1 then
480   // default color is used.
481   myTexture = "";
482
483   myWidth = -1;
484   myType = -1;
485   myToActivate = true;
486   // This parameter is used for activisation/deactivisation of objects to be displayed
487
488   #if OCC_VERSION_LARGE > 0x06050100 // Functionnality available only in OCCT 6.5.2
489   // Activate parallel vizualisation only for testing purpose
490   // and if the corresponding env variable is set to 1
491   char* parallel_visu = getenv("PARALLEL_VISU");
492   if (parallel_visu && atoi(parallel_visu))
493   {
494     MESSAGE("Parallel visualisation on");
495     BRepMesh_IncrementalMesh::SetParallelDefault(Standard_True);
496   }
497   #endif
498
499   myViewFrame = 0;
500
501   myFieldDataType = GEOM::FDT_Double;
502   myFieldDimension = 0;
503   myFieldStepRangeMin = 0;
504   myFieldStepRangeMax = 0;
505 }
506
507 //=================================================================
508 /*!
509  *  GEOM_Displayer::~GEOM_Displayer
510  *  Destructor
511  */
512 //=================================================================
513 GEOM_Displayer::~GEOM_Displayer()
514 {
515 }
516
517 //=================================================================
518 /*!
519  *  GEOM_Displayer::Display
520  *  Display interactive object in the current viewer
521  */
522 //=================================================================
523 void GEOM_Displayer::Display( const Handle(SALOME_InteractiveObject)& theIO,
524                              const bool updateViewer,
525                              SALOME_View* theViewFrame )
526 {
527   SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView();
528   if ( vf )
529   {
530     SALOME_Prs* prs = buildPresentation( theIO->getEntry(), vf );
531
532     if ( prs )
533     {
534       vf->BeforeDisplay( this, prs );
535       vf->Display( prs );
536       vf->AfterDisplay( this, prs );
537
538       if ( updateViewer )
539         vf->Repaint();
540
541       int aMgrId = getViewManagerId(vf);
542       SalomeApp_Study* aStudy = getStudy();
543       aStudy->setObjectProperty(aMgrId, theIO->getEntry(), GEOM::propertyName( GEOM::Visibility ), 1 );
544
545       setVisibilityState(theIO->getEntry(), Qtx::ShownState);
546
547       delete prs;  // delete presentation because displayer is its owner
548     }
549   }
550 }
551
552 //=================================================================
553 /*!
554  *  GEOM_Displayer::Display
555  *  This overloaded Display() method can be useful for operations
556  *  not using dialog boxes.
557  */
558 //=================================================================
559 void GEOM_Displayer::Display( GEOM::GEOM_BaseObject_ptr theObj, const bool updateViewer )
560 {
561   if ( theObj->_is_nil() )
562     return;
563
564   std::string entry = getEntry( theObj );
565   if ( entry != "" ) {
566     Display(new SALOME_InteractiveObject(entry.c_str(), "GEOM", getName(theObj).c_str()),
567             updateViewer);
568   }
569 }
570
571 //=================================================================
572 /*!
573  *  GEOM_Displayer::Erase
574  *  Erase interactive object in the current viewer
575  */
576 //=================================================================
577 void GEOM_Displayer::Erase( const Handle(SALOME_InteractiveObject)& theIO,
578                             const bool forced,
579                             const bool updateViewer,
580                             SALOME_View* theViewFrame )
581 {
582   if ( theIO.IsNull() )
583     return;
584
585   SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView();
586
587   if ( vf ) {
588     SALOME_Prs* prs = vf->CreatePrs( theIO->getEntry() );
589     if ( prs ) {
590       vf->BeforeErase( this, prs );
591       vf->Erase( prs, forced );
592       vf->AfterErase( this, prs );
593       if ( updateViewer )
594         vf->Repaint();
595       delete prs;  // delete presentation because displayer is its owner
596
597       int aMgrId = getViewManagerId(vf);
598       SalomeApp_Study* aStudy = getStudy();
599       aStudy->setObjectProperty(aMgrId, theIO->getEntry(), GEOM::propertyName( GEOM::Visibility ), 0 );
600
601       setVisibilityState(theIO->getEntry(), Qtx::HiddenState);
602     }
603   }
604 }
605
606 //=================================================================
607 /*!
608  *  GEOM_Displayer::Erase
609  *  Erase geometry object in the current viewer
610  */
611 //=================================================================
612 void GEOM_Displayer::Erase( GEOM::GEOM_BaseObject_ptr theObj,
613                             const bool forced,
614                             const bool updateViewer,
615                             SALOME_View* theViewFrame)
616 {
617   std::string entry = getEntry( theObj );
618   if ( entry != "" )
619   {
620     Erase(new SALOME_InteractiveObject(entry.c_str(), "GEOM", getName(theObj).c_str()),
621           forced, updateViewer, theViewFrame);
622   }
623 }
624
625 //=================================================================
626 /*!
627  *  GEOM_Displayer::Redisplay
628  *  Redisplay (erase and then display again) interactive object
629  *  in the current viewer
630  */
631 //=================================================================
632 void GEOM_Displayer::Redisplay( const Handle(SALOME_InteractiveObject)& theIO,
633                                 const bool updateViewer,
634                                 const bool checkActiveViewer )
635 {
636   // Remove the object permanently (<forced> == true)
637   SUIT_Session* ses = SUIT_Session::session();
638   SUIT_Application* app = ses->activeApplication();
639   if ( app )
640   {
641     SUIT_Desktop* desk = app->desktop();
642     QList<SUIT_ViewWindow*> wnds = desk->windows();
643     SUIT_ViewWindow* wnd;
644     QListIterator<SUIT_ViewWindow*> it( wnds );
645     while ( it.hasNext() && (wnd = it.next()) )
646     {
647       SUIT_ViewManager* vman = wnd->getViewManager();
648       if ( vman )
649       {
650         SUIT_ViewModel* vmodel = vman->getViewModel();
651         if ( vmodel )
652         {
653           SALOME_View* view = dynamic_cast<SALOME_View*>(vmodel);
654           if ( view )
655           {
656             if ( view->isVisible( theIO ) || ( checkActiveViewer && view == GetActiveView() ) )
657             {
658               Redisplay( theIO, updateViewer, view );
659             }
660           }
661         }
662       }
663     }
664   }
665 }
666
667 //=================================================================
668 /*!
669  *  GEOM_Displayer::Redisplay
670  *  Redisplay (erase and then display again) interactive object
671  *  in the specified view
672  */
673 //=================================================================
674 void GEOM_Displayer::Redisplay( const Handle(SALOME_InteractiveObject)& theIO,
675                                 const bool theUpdateViewer,
676                                 SALOME_View* theViewFrame )
677 {
678   SALOME_View* vf = theViewFrame ? theViewFrame : GetActiveView();
679   if ( !vf )
680   {
681     return;
682   }
683
684   Erase( theIO, true, false, theViewFrame );
685   Display( theIO, theUpdateViewer, theViewFrame );
686 }
687
688 //=================================================================
689 /*!
690  *  GEOM_Displayer::Display
691  *  Calls Display() method for each object in the given list
692  */
693 //=================================================================
694 void GEOM_Displayer::Display( const SALOME_ListIO& theIOList, const bool updateViewer )
695 {
696   SALOME_ListIteratorOfListIO Iter( theIOList );
697   for ( ; Iter.More(); Iter.Next() ) {
698     Display( Iter.Value(), false );
699   }
700   if ( updateViewer )
701     UpdateViewer();
702 }
703
704 Quantity_Color GEOM_Displayer::qColorFromResources( const QString& property, const QColor& defColor )
705 {
706   // VSR: this method can be improved in future:
707   // to improve performance, the default values from resource manager should be cached in the displayer
708   return SalomeApp_Tools::color( SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", property, defColor ) );
709 }
710
711 QColor GEOM_Displayer::colorFromResources( const QString& property, const QColor& defColor )
712 {
713   // VSR: this method can be improved in future:
714   // to improve performance, the default values from resource manager should be cached in the displayer
715   return SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", property, defColor );
716 }
717
718 void GEOM_Displayer::updateShapeProperties( const Handle(GEOM_AISShape)& AISShape, bool create )
719 {
720   // check that shape is not null
721   if ( AISShape.IsNull() ) return;
722   
723   // check that study is active
724   SalomeApp_Study* study = getStudy();
725   if ( !study ) return;
726
727   if ( myShape.ShapeType() != TopAbs_VERTEX && // fix pb with not displayed points
728        !TopoDS_Iterator(myShape).More() )
729     return; // NPAL15983 (Bug when displaying empty groups)
730
731   // set interactive object
732
733   Handle( SALOME_InteractiveObject ) anIO;
734
735   if ( !myIO.IsNull() ) {
736     AISShape->setIO( myIO );
737     AISShape->SetOwner( myIO );
738     anIO = myIO;
739   }
740   else if ( !myName.empty() ) {
741     // workaround to allow selection of temporary objects
742     static int tempId = 0;
743     anIO = new SALOME_InteractiveObject( QString( "TEMP_%1" ).arg( tempId++ ).toLatin1().data(), "GEOM", myName.c_str() );
744     AISShape->setIO( anIO );
745     AISShape->SetOwner( anIO );
746   }
747
748   // flag:  only vertex or compound of vertices is processed (specific handling)
749   bool onlyVertex = myShape.ShapeType() == TopAbs_VERTEX || isCompoundOfVertices( myShape );
750   // presentation study entry (empty for temporary objects like preview)
751   QString entry = !anIO.IsNull() ? QString( anIO->getEntry() ) : QString();
752   // flag: temporary object
753   bool isTemporary = entry.isEmpty() || entry.startsWith( "TEMP_" );
754   // currently active view window's ID (-1 if no active view)
755   int aMgrId = !anIO.IsNull() ? getViewManagerId( myViewFrame ) : -1;
756
757   // get presentation properties
758   PropMap propMap = getObjectProperties( study, entry, myViewFrame );
759
760   // Temporary staff: vertex must be infinite for correct visualization
761   AISShape->SetInfiniteState( myShape.Infinite() ); // || myShape.ShapeType() == TopAbs_VERTEX // VSR: 05/04/2010: Fix 20668 (Fit All for points & lines)
762
763   // set material
764   Material_Model material;
765   // if predefined color isn't set in displayer(via GEOM_Displayer::SetColor() function)
766   if( !HasColor() )
767     material.fromProperties( propMap.value( GEOM::propertyName( GEOM::Material ) ).toString() );
768   // - set front material properties
769   AISShape->SetCurrentFacingModel( Aspect_TOFM_FRONT_SIDE );
770   AISShape->SetMaterial( material.getMaterialOCCAspect( true ) );
771   // - set back material properties
772   AISShape->SetCurrentFacingModel( Aspect_TOFM_BACK_SIDE );
773   AISShape->SetMaterial( material.getMaterialOCCAspect( false ) );
774   // - switch to default (both sides) facing mode
775   AISShape->SetCurrentFacingModel( Aspect_TOFM_BOTH_SIDE );
776
777   // set colors
778
779   // - shading color
780   if ( HasColor()  ) {
781     // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function;
782     // we set it to the shape not taking into account material properties
783     AISShape->SetShadingColor( (Quantity_NameOfColor)GetColor() );
784   }
785   else if ( !material.isPhysical() ) {
786     // shading color from properties is used only for non-physical materials
787     AISShape->SetShadingColor( SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::ShadingColor ) ).value<QColor>() ) );
788   }
789
790   // - wireframe color
791   Handle(Prs3d_LineAspect) anAspect = AISShape->Attributes()->LineAspect();
792   anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : 
793                       SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::WireframeColor ) ).value<QColor>() ) );
794   AISShape->Attributes()->SetLineAspect( anAspect );
795   
796   // - unfree boundaries color
797   anAspect = AISShape->Attributes()->UnFreeBoundaryAspect();
798   anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : 
799                       SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::WireframeColor ) ).value<QColor>() ) );
800   AISShape->Attributes()->SetUnFreeBoundaryAspect( anAspect );
801   
802   // - free boundaries color
803   anAspect = AISShape->Attributes()->FreeBoundaryAspect();
804   anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : 
805                       SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::FreeBndColor ) ).value<QColor>() ) );
806   AISShape->Attributes()->SetFreeBoundaryAspect( anAspect );
807   
808   // - standalone edges color
809   anAspect = AISShape->Attributes()->WireAspect();
810   anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : 
811                       SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::LineColor ) ).value<QColor>() ) );
812   AISShape->Attributes()->SetWireAspect( anAspect );
813   
814   // - color for edges in shading+edges mode
815   AISShape->SetEdgesInShadingColor( SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::OutlineColor ) ).value<QColor>() ) );
816
817   // set display mode
818   AISShape->SetDisplayMode( HasDisplayMode() ? 
819                             // predefined display mode, manually set to displayer via GEOM_Displayer::SetDisplayMode() function 
820                             GetDisplayMode() :
821                             // display mode from properties
822                             propMap.value( GEOM::propertyName( GEOM::DisplayMode ) ).toInt() );
823
824   // - face boundaries color
825   if( AISShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges )
826     AISShape->Attributes()->SetFaceBoundaryDraw( Standard_True );
827   anAspect = AISShape->Attributes()->FaceBoundaryAspect();
828   anAspect->SetColor( SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::OutlineColor ) ).value<QColor>() ) );
829   AISShape->Attributes()->SetFaceBoundaryAspect( anAspect );
830
831   // set display vectors flag
832   AISShape->SetDisplayVectors( propMap.value( GEOM::propertyName( GEOM::EdgesDirection ) ).toBool() );
833
834   // set display vertices flag
835   AISShape->SetDisplayVertices( propMap.value( GEOM::propertyName( GEOM::Vertices ) ).toBool() );
836
837   // set transparency
838   if( HasTransparency() ) {
839     AISShape->SetTransparency( GetTransparency() );
840   } else {
841     AISShape->SetTransparency( propMap.value( GEOM::propertyName( GEOM::Transparency ) ).toDouble() );
842   }
843
844   // set iso properties
845   int uIsos = propMap.value( GEOM::propertyName( GEOM::NbIsos ) ).toString().split( GEOM::subSectionSeparator() )[0].toInt();
846   int vIsos = propMap.value( GEOM::propertyName( GEOM::NbIsos ) ).toString().split( GEOM::subSectionSeparator() )[1].toInt();
847   Quantity_Color isosColor = SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::IsosColor ) ).value<QColor>() );
848   int isosWidth = propMap.value( GEOM::propertyName( GEOM::IsosWidth ) ).toInt();
849   Handle(Prs3d_IsoAspect) uIsoAspect = AISShape->Attributes()->UIsoAspect();
850   Handle(Prs3d_IsoAspect) vIsoAspect = AISShape->Attributes()->VIsoAspect();
851   uIsoAspect->SetColor( isosColor );
852   uIsoAspect->SetWidth( isosWidth );
853   uIsoAspect->SetNumber( uIsos );
854   vIsoAspect->SetColor( isosColor );
855   vIsoAspect->SetWidth( isosWidth );
856   vIsoAspect->SetNumber( vIsos );
857   AISShape->Attributes()->SetUIsoAspect( uIsoAspect );
858   AISShape->Attributes()->SetVIsoAspect( vIsoAspect );
859
860   // set deflection coefficient
861   // ... to avoid to small values of the coefficient, its lower value is limited 
862   AISShape->SetOwnDeviationCoefficient( qMax( propMap.value( GEOM::propertyName( GEOM::Deflection ) ).toDouble(), GEOM::minDeflection() ) );
863
864   // set texture
865   QString aImagePath;
866   if ( HasTexture() ) {
867     // predefined display texture, manually set to displayer via GEOM_Displayer::SetTexture() function 
868     aImagePath = GetTexture().c_str();
869     if ( ! entry.isEmpty() ) {
870       // check that study is active
871       SalomeApp_Study* study = getActiveStudy();
872       if ( study ) {
873         // Store the texture in object properties for next displays
874         study->setObjectProperty( aMgrId, entry, GEOM::propertyName( GEOM::Texture ), QString( GetTexture().c_str() ) );
875         study->setObjectProperty( aMgrId, entry, GEOM::propertyName( GEOM::DisplayMode ), 3 );
876         
877         // Update propeties map
878         propMap = getObjectProperties( study, entry, myViewFrame );
879       }
880     }
881   }
882   else {
883     aImagePath = propMap.value( GEOM::propertyName( GEOM::Texture ) ).toString();
884   }
885
886 #if OCC_VERSION_LARGE > 0x06070000
887   Handle(Image_PixMap) aPixmap;
888   if ( !aImagePath.isEmpty() )
889     aPixmap = cacheTextureFor( aImagePath, AISShape );
890   else
891     aPixmap = getDefaultTexture();
892
893   // apply image to shape
894   if ( !aPixmap.IsNull() ) {
895     AISShape->SetTexturePixMap( aPixmap );
896     AISShape->SetTextureMapOn();
897     AISShape->DisableTextureModulate();
898   }
899   else {
900     AISShape->SetTextureMapOff();
901   }
902 #else
903   if ( !aImagePath.isEmpty() ) {
904     AISShape->SetTextureFileName( TCollection_AsciiString( aImagePath.toUtf8().constData() ) );
905     AISShape->SetTextureMapOn();
906     AISShape->DisableTextureModulate();
907   }
908 #endif
909
910   // set line width
911   AISShape->SetWidth( HasWidth() ?
912                       // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function 
913                       GetWidth() :
914                       // libe width from properties
915                       propMap.value( GEOM::propertyName( GEOM::LineWidth ) ).toInt() );
916
917   // set top-level flag
918   AISShape->setTopLevel( propMap.value( GEOM::propertyName( GEOM::TopLevel ) ).toBool() );
919
920   // set point marker (for vertex / compound of vertices only)
921   if ( onlyVertex ) {
922     QStringList aList = propMap.value( GEOM::propertyName( GEOM::PointMarker ) ).toString().split( GEOM::subSectionSeparator() );
923     if ( aList.size() == 2 ) {
924       // standard marker string contains "TypeOfMarker:ScaleOfMarker"
925       int aTypeOfMarker = aList[0].toInt();
926       double aScaleOfMarker = (aList[1].toInt() + 1) * 0.5;
927       Handle(Prs3d_PointAspect) anAspect = AISShape->Attributes()->PointAspect();
928       anAspect->SetScale( aScaleOfMarker );
929       anAspect->SetTypeOfMarker( (Aspect_TypeOfMarker)( aTypeOfMarker-1 ) );
930       anAspect->SetColor( HasColor() ? 
931                           // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function
932                           (Quantity_NameOfColor)GetColor() : 
933                           // color from properties
934                           SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::PointColor ) ).value<QColor>() ) );
935       AISShape->Attributes()->SetPointAspect( anAspect );
936     }
937     else if ( aList.size() == 1 ) {
938       // custom marker string contains "IdOfTexture"
939       int textureId = aList[0].toInt();
940       Standard_Integer aWidth, aHeight;
941 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
942       Handle(TColStd_HArray1OfByte) aTexture =
943 #else
944         Handle(Graphic3d_HArray1OfBytes) aTexture =
945 #endif
946         GeometryGUI::getTexture( study, textureId, aWidth, aHeight );
947       if ( !aTexture.IsNull() ) {
948 #if OCC_VERSION_LARGE > 0x06060000 // Porting to OCCT higher 6.6.0 version
949         Handle(Prs3d_PointAspect) aTextureAspect =
950           new Prs3d_PointAspect( HasColor() ? 
951                                  // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function
952                                  (Quantity_NameOfColor)GetColor() : 
953                                  // color from properties 
954                                  SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::PointColor ) ).value<QColor>() ),
955                                  aWidth, aHeight,
956                                  aTexture );
957 #else
958         int TextureId = 0;
959         Handle(Prs3d_PointAspect) aTextureAspect =
960           new Prs3d_PointAspect( HasColor() ? 
961                                  // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function
962                                  (Quantity_NameOfColor)GetColor() : 
963                                  // color from properties 
964                                  SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::PointColor ) ).value<QColor>() ), 
965                                  ++TextureId,
966                                  aWidth, aHeight,
967                                  aTexture );
968 #endif
969         AISShape->Attributes()->SetPointAspect( aTextureAspect );
970       }
971     }
972   }
973
974   // set field step data
975   AISShape->setFieldStepInfo( myFieldDataType,
976                               myFieldDimension,
977                               myFieldStepData,
978                               myFieldStepName,
979                               myFieldStepRangeMin,
980                               myFieldStepRangeMax );
981
982   if ( create && !isTemporary && aMgrId != -1 ) {
983     // set properties to the study
984     study->setObjectPropMap( aMgrId, entry, propMap );
985   }
986
987   // AISShape->SetName(???); ??? necessary to set name ???
988 }
989
990 void GEOM_Displayer::updateActorProperties( GEOM_Actor* actor, bool create )
991 {
992   // check that actor is not null
993   if ( !actor ) return;
994   
995   // check that study is active
996   SalomeApp_Study* study = getStudy();
997   if ( !study ) return;
998
999   // set interactive object
1000
1001   Handle( SALOME_InteractiveObject ) anIO;
1002
1003   if ( !myIO.IsNull() ) {
1004     actor->setIO( myIO );
1005     anIO = myIO;
1006   }
1007   else if ( !myName.empty() ) {
1008     // workaround to allow selection of temporary objects
1009     static int tempId = 0;
1010     anIO = new SALOME_InteractiveObject( QString( "TEMP_VTK_%1" ).arg( tempId++ ).toLatin1().data(), "GEOM", myName.c_str() );
1011     actor->setIO( anIO );
1012   }
1013
1014   // presentation study entry (empty for temporary objects like preview)
1015   QString entry = !anIO.IsNull() ? QString( anIO->getEntry() ) : QString();
1016   // flag: temporary object
1017   bool isTemporary = entry.isEmpty() || entry.startsWith( "TEMP_" );
1018   // currently active view window's ID (-1 if no active view)
1019   int aMgrId = !anIO.IsNull() ? getViewManagerId( myViewFrame ) : -1;
1020
1021   // get presentation properties
1022   PropMap propMap = getObjectProperties( study, entry, myViewFrame );
1023   QColor c;
1024
1025   /////////////////////////////////////////////////////////////////////////
1026   // VSR: for VTK viewer currently deflection coefficient is hardcoded
1027   //      due to performance problem
1028   // actor->SetShape(myShape,aDefPropMap.value(GEOM::propertyName( GEOM::Deflection )).toDouble(),myType == GEOM_VECTOR);
1029   /////////////////////////////////////////////////////////////////////////
1030   if ( !actor->getTopo().IsSame( myShape ) )
1031     actor->SetShape( myShape, VTK_MIN_DEFLECTION, myType == GEOM_VECTOR );
1032
1033   // set material
1034   Material_Model material;
1035   material.fromProperties( propMap.value( GEOM::propertyName( GEOM::Material ) ).toString() );
1036   std::vector<vtkProperty*> mprops;
1037   mprops.push_back( material.getMaterialVTKProperty( true ) );
1038   mprops.push_back( material.getMaterialVTKProperty( false) );
1039   actor->SetMaterial( mprops );
1040
1041   // set iso-lines properties
1042
1043   // - set number of iso-lines
1044   int nbIsos[2]= { 1, 1 };
1045   QStringList isos = propMap.value( GEOM::propertyName( GEOM::NbIsos ) ).toString().split( GEOM::subSectionSeparator() );
1046   nbIsos[0] = isos[0].toInt();
1047   nbIsos[1] = isos[1].toInt();
1048   actor->SetNbIsos( nbIsos );
1049
1050   // - set iso-lines width
1051   actor->SetIsosWidth( propMap.value( GEOM::propertyName( GEOM::IsosWidth ) ).toInt() );
1052
1053   // - set iso-lines color
1054   c = propMap.value( GEOM::propertyName( GEOM::IsosColor ) ).value<QColor>();
1055   actor->SetIsosColor( c.redF(), c.greenF(), c.blueF() );
1056
1057   // set colors
1058
1059   if ( HasColor()  ) {
1060     // - same color for all sub-actors
1061     Quantity_Color aColor( (Quantity_NameOfColor)GetColor() );
1062     actor->SetColor( aColor.Red(), aColor.Green(), aColor.Blue() );
1063   }
1064   else {
1065     // shading color (for non-physical materials)
1066     if ( !material.isPhysical() ) {
1067       c = propMap.value( GEOM::propertyName( GEOM::ShadingColor ) ).value<QColor>();
1068       actor->GetFrontMaterial()->SetColor( c.redF(), c.greenF(), c.blueF() );
1069       actor->GetBackMaterial()->SetColor( c.redF(), c.greenF(), c.blueF() );
1070     }
1071
1072     // - standalone edge color
1073     c = propMap.value( GEOM::propertyName( GEOM::LineColor ) ).value<QColor>();
1074     actor->SetIsolatedEdgeColor( c.redF(), c.greenF(), c.blueF() );
1075
1076     c = propMap.value( GEOM::propertyName( GEOM::WireframeColor ) ).value<QColor>();
1077     // - shared edges color ???
1078     actor->SetSharedEdgeColor( c.redF(), c.greenF(), c.blueF() );
1079
1080     c = propMap.value( GEOM::propertyName( GEOM::FreeBndColor ) ).value<QColor>();
1081     // - free edges color ???
1082     actor->SetFreeEdgeColor( c.redF(), c.greenF(), c.blueF() );
1083
1084     // - point color
1085     c = propMap.value( GEOM::propertyName( GEOM::PointColor ) ).value<QColor>();
1086     actor->SetPointColor( c.redF(), c.greenF(), c.blueF() );
1087   }
1088
1089   // - color for edges in shading+edges mode
1090   c = propMap.value( GEOM::propertyName( GEOM::OutlineColor ) ).value<QColor>();
1091   actor->SetEdgesInShadingColor( c.redF(), c.greenF(), c.blueF() );
1092
1093   // set opacity
1094   if( HasTransparency() ) {
1095     actor->SetOpacity( 1.0 - GetTransparency() );
1096   } else {
1097     actor->SetOpacity( 1.0 - propMap.value( GEOM::propertyName( GEOM::Transparency ) ).toDouble() );
1098   }
1099
1100   // set line width
1101   actor->SetWidth( HasWidth() ?
1102                    // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function 
1103                    GetWidth() :
1104                    // libe width from properties
1105                    propMap.value( GEOM::propertyName( GEOM::LineWidth ) ).toInt() );
1106   
1107   // set display vectors flag
1108   actor->SetVectorMode( propMap.value( GEOM::propertyName( GEOM::EdgesDirection ) ).toBool() );
1109
1110   // set display vertices flag
1111   actor->SetVerticesMode( propMap.value( GEOM::propertyName( GEOM::Vertices ) ).toBool() );
1112
1113   // set display mode
1114   int displayMode = HasDisplayMode() ? 
1115     // predefined display mode, manually set to displayer via GEOM_Displayer::SetDisplayMode() function 
1116     GetDisplayMode() :
1117     // display mode from properties
1118     propMap.value( GEOM::propertyName( GEOM::DisplayMode ) ).toInt();
1119
1120   // specific processing of 'shading with edges' mode, as VTK provides only the following standard display modes:
1121   // Points - 0, Wireframe - 1, Surface - 2, Insideframe - 3, SurfaceWithEdges - 4
1122   // GEOM actor allows alternative display modes (see VTKViewer::Representation enum) and enum in GEOM_Actor:
1123   // eWireframe - 0, eShading - 1, eShadingWithEdges - 3
1124
1125   if ( displayMode == 2 )
1126       // this is 'Shading with edges' mode => we have to do the correct mapping to EDisplayMode
1127       // enum in GEOM_Actor (and further to VTKViewer::Representation enum)
1128     displayMode++;
1129   actor->setDisplayMode( displayMode );
1130
1131   if ( myToActivate )
1132     actor->PickableOn();
1133   else
1134     actor->PickableOff();
1135
1136   if ( create && !isTemporary && aMgrId != -1 ) {
1137     // set properties to the study
1138     study->setObjectPropMap( aMgrId, entry, propMap );
1139   }
1140 }
1141
1142 //=================================================================
1143 /*!
1144  *  GEOM_Displayer::updateDimensions
1145  *  Creates or renews dimension presentation for the IO.
1146  */
1147 //=================================================================
1148 void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& theIO,
1149                                        SALOME_OCCPrs* thePrs,
1150                                        const gp_Ax3& theShapeLCS )
1151 {
1152   SalomeApp_Study* aStudy = getStudy();
1153   if ( !aStudy )
1154   {
1155     return;
1156   }
1157
1158   if ( theIO.IsNull() )
1159   {
1160     return;
1161   }
1162
1163   SOCC_Prs* anOccPrs = dynamic_cast<SOCC_Prs*>( thePrs );
1164
1165   AIS_ListOfInteractive aListOfIO;
1166
1167   anOccPrs->GetObjects( aListOfIO );
1168
1169   AIS_ListIteratorOfListOfInteractive aIterateIO( aListOfIO );
1170
1171   // remove outdated presentations of dimensions
1172   for ( ; aIterateIO.More(); aIterateIO.Next() )
1173   {
1174     const Handle(AIS_InteractiveObject)& anIO = aIterateIO.Value();
1175     if ( !anIO->IsKind( STANDARD_TYPE( AIS_Dimension ) ) )
1176     {
1177       continue;
1178     }
1179
1180     aListOfIO.Remove( aIterateIO );
1181
1182     if ( !aIterateIO.More() )
1183     {
1184       break;
1185     }
1186   }
1187
1188   // prepare dimension styling
1189   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1190
1191   QColor  aQColor       = aResMgr->colorValue  ( "Geometry", "dimensions_color", QColor( 0, 255, 0 ) );
1192   int     aLineWidth    = aResMgr->integerValue( "Geometry", "dimensions_line_width", 1 );
1193   double  aFontHeight   = aResMgr->doubleValue ( "Geometry", "dimensions_font_height", 10 );
1194   double  anArrowLength = aResMgr->doubleValue ( "Geometry", "dimensions_arrow_length", 5 );
1195   bool    isUnitsShown  = aResMgr->booleanValue( "Geometry", "dimensions_show_units", false );
1196   QString aUnitsLength  = aResMgr->stringValue ( "Geometry", "dimensions_length_units", "m" );
1197   QString aUnitsAngle   = aResMgr->stringValue ( "Geometry", "dimensions_angle_units", "deg" );
1198
1199   // restore dimension presentation from saved attribute or property data
1200   AIS_ListOfInteractive aRestoredDimensions;
1201
1202   QVariant aProperty = aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
1203                                                   theIO->getEntry(),
1204                                                   GEOM::propertyName( GEOM::Dimensions ),
1205                                                   QVariant() );
1206
1207   GEOMGUI_DimensionProperty aRecords;
1208
1209   if ( aProperty.isValid() && aProperty.canConvert<GEOMGUI_DimensionProperty>() )
1210   {
1211     aRecords = aProperty.value<GEOMGUI_DimensionProperty>();
1212   }
1213   else
1214   {
1215     aRecords.LoadFromAttribute( getStudy(), theIO->getEntry() );
1216   }
1217   
1218   // create up-to-date dimension presentations
1219   for ( int aPrsIt = 0; aPrsIt < aRecords.GetNumber(); ++aPrsIt )
1220   {
1221     if ( !aRecords.IsVisible( aPrsIt ) )
1222     {
1223       continue;
1224     }
1225
1226     // init dimension by type
1227     Handle(AIS_Dimension) aPrs;
1228     switch( aRecords.GetType( aPrsIt ) )
1229     {
1230       case GEOMGUI_DimensionProperty::DimensionType_Length :
1231       {
1232         Handle(GEOM_AISLength) aLength = new GEOM_AISLength( aPrsIt );
1233         aRecords.GetRecord( aPrsIt )->AsLength()->Update( aLength, theShapeLCS );
1234         aPrs = aLength;
1235         break;
1236       }
1237
1238       case GEOMGUI_DimensionProperty::DimensionType_Diameter :
1239       {
1240         Handle(GEOM_AISDiameter) aDiam = new GEOM_AISDiameter( aPrsIt );
1241         aRecords.GetRecord( aPrsIt )->AsDiameter()->Update( aDiam, theShapeLCS );
1242         aPrs = aDiam;
1243         break;
1244       }
1245
1246       case GEOMGUI_DimensionProperty::DimensionType_Angle :
1247       {
1248         Handle(GEOM_AISAngle) anAng = new GEOM_AISAngle( aPrsIt );
1249         aRecords.GetRecord( aPrsIt )->AsAngle()->Update( anAng, theShapeLCS );
1250         aPrs = anAng;
1251         break;
1252       }
1253     }
1254
1255     aPrs->SetOwner( theIO );
1256
1257     Quantity_Color aColor( aQColor.redF(), aQColor.greenF(), aQColor.blueF(), Quantity_TOC_RGB );
1258
1259     Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
1260
1261     aStyle->SetCommonColor( aColor );
1262     aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
1263     aStyle->MakeText3d( Standard_True );
1264     aStyle->MakeTextShaded( Standard_True );
1265     aStyle->SetExtensionSize( aFontHeight * 0.5 );
1266     aStyle->TextAspect()->SetHeight( aFontHeight );
1267     aStyle->ArrowAspect()->SetLength( anArrowLength );
1268     aStyle->LineAspect()->SetWidth( aLineWidth );
1269     aStyle->SetTextHorizontalPosition( aPrs->DimensionAspect()->TextHorizontalPosition() );
1270     aStyle->SetTextVerticalPosition( aPrs->DimensionAspect()->TextVerticalPosition() );
1271     aStyle->SetArrowOrientation( aPrs->DimensionAspect()->ArrowOrientation() );
1272     aPrs->SetDimensionAspect( aStyle );
1273     aPrs->SetPolygonOffsets( Aspect_POM_Fill, -1.0, -1.0 );
1274     aPrs->Attributes()->SetDimLengthDisplayUnits( aUnitsLength.toLatin1().data() );
1275     aPrs->Attributes()->SetDimAngleDisplayUnits( aUnitsAngle.toLatin1().data() );
1276
1277     if ( aPrs->IsKind( STANDARD_TYPE(AIS_AngleDimension) ) )
1278     {
1279       // show degree symbol for dimension instead of label "deg"
1280       if ( aUnitsAngle == "deg" )
1281       {
1282         aPrs->SetSpecialSymbol(0xB0);
1283         aPrs->SetDisplaySpecialSymbol( isUnitsShown ? AIS_DSS_After : AIS_DSS_No );
1284         aStyle->MakeUnitsDisplayed(Standard_False);
1285       }
1286       else
1287       {
1288         aPrs->SetDisplaySpecialSymbol(AIS_DSS_No);
1289         aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
1290       }
1291     }
1292     else
1293     {
1294       aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
1295     }
1296
1297     aListOfIO.Append( aPrs );
1298   }
1299
1300   // update presentation
1301   anOccPrs->Clear();
1302
1303   for ( aIterateIO.Initialize( aListOfIO ); aIterateIO.More(); aIterateIO.Next() )
1304   {
1305     anOccPrs->AddObject( aIterateIO.Value() );
1306   }
1307 }
1308
1309 //=================================================================
1310 /*!
1311  *  GEOM_Displayer::Erase
1312  *  Calls Erase() method for each object in the given list
1313  */
1314 //=================================================================
1315 void GEOM_Displayer::Erase( const SALOME_ListIO& theIOList,
1316                             const bool forced,
1317                             const bool updateViewer )
1318 {
1319   SALOME_ListIteratorOfListIO Iter( theIOList );
1320   for ( ; Iter.More(); Iter.Next() )
1321     Erase( Iter.Value(), forced, false );
1322
1323   if ( updateViewer )
1324     UpdateViewer();
1325 }
1326
1327 //=================================================================
1328 /*!
1329  *  GEOM_Displayer::Redisplay
1330  *  Calls Redisplay() method for each object in the given list
1331  */
1332 //=================================================================
1333 void GEOM_Displayer::Redisplay( const SALOME_ListIO& theIOList,
1334                                 const bool updateViewer,
1335                                 const bool checkActiveViewer )
1336 {
1337   SALOME_ListIteratorOfListIO Iter( theIOList );
1338   for ( ; Iter.More(); Iter.Next() )
1339     Redisplay( Iter.Value(), false, checkActiveViewer );
1340
1341   if ( updateViewer )
1342     UpdateViewer();
1343 }
1344
1345 //=================================================================
1346 /*!
1347  *  GEOM_Displayer::Redisplay
1348  *  Calls Redisplay() method for each object in the given list
1349  */
1350 //=================================================================
1351 void GEOM_Displayer::Redisplay( const SALOME_ListIO& theIOList,
1352                                 const bool theUpdateViewer,
1353                                 SALOME_View* theViewFrame )
1354 {
1355   SALOME_ListIteratorOfListIO anIter( theIOList );
1356   for ( ; anIter.More(); anIter.Next() )
1357   {
1358     Redisplay( anIter.Value(), false, theViewFrame );
1359   }
1360
1361   if ( theUpdateViewer )
1362   {
1363     UpdateViewer();
1364   }
1365 }
1366
1367 //=================================================================
1368 /*!
1369  *  GEOM_Displayer::Update
1370  *  Update OCC presentaion
1371  *  [ Reimplemented from SALOME_Displayer ]
1372  */
1373 //=================================================================
1374 void GEOM_Displayer::Update( SALOME_OCCPrs* prs )
1375 {
1376   SOCC_Prs* occPrs = dynamic_cast<SOCC_Prs*>( prs );
1377   SalomeApp_Study* study = getStudy();
1378
1379   if ( !occPrs || myShape.IsNull() || !study )
1380     return;
1381
1382   if ( myType == GEOM_MARKER && myShape.ShapeType() == TopAbs_FACE )
1383   {
1384     // 
1385     // specific processing for local coordinate system presentation
1386     // 
1387
1388     TopoDS_Face aFace = TopoDS::Face( myShape );
1389     Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( aFace ) );
1390     if ( !aPlane.IsNull() )
1391     {
1392       gp_Ax3 aPos = aPlane->Pln().Position();
1393       Handle(Geom_Axis2Placement) aPlc = new Geom_Axis2Placement( aPos.Ax2() );
1394
1395       Handle(GEOM_AISTrihedron) aTrh;
1396
1397       if ( occPrs->IsNull() )
1398       {
1399         // new presentation is being created
1400         aTrh = new GEOM_AISTrihedron( aPlc );
1401         occPrs->AddObject( aTrh );
1402       }
1403       else
1404       {
1405         // presentation is being updated
1406         AIS_ListOfInteractive aList;
1407         occPrs->GetObjects( aList );
1408         AIS_ListIteratorOfListOfInteractive anIter( aList );
1409         for ( ; anIter.More() && aTrh.IsNull(); anIter.Next() ) {
1410           aTrh = Handle(GEOM_AISTrihedron)::DownCast( anIter.Value() );
1411         }
1412       }
1413         
1414       if ( !aTrh.IsNull() ) {
1415         // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function
1416         if ( HasColor() )
1417           aTrh->SetColor( (Quantity_NameOfColor)GetColor() );
1418         // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function 
1419         if ( HasWidth() )
1420           aTrh->SetWidth( GetWidth() );
1421         
1422         if ( !myIO.IsNull() )
1423         {
1424           aTrh->setIO( myIO );
1425           aTrh->SetOwner( myIO );
1426         }
1427         aTrh->SetComponent( aPlc );
1428         aTrh->SetToUpdate();
1429       }
1430       occPrs->SetToActivate( ToActivate() );
1431     }
1432   }
1433   else
1434   {
1435     // 
1436     // processing for usual geometry presentation
1437     // 
1438
1439     // if presentation is empty we try to create new one
1440     if ( occPrs->IsNull() )
1441     {
1442       // create presentation (specific for vectors)
1443       Handle(GEOM_AISShape) AISShape = ( myType == GEOM_VECTOR ) ? new GEOM_AISVector( myShape, "" )
1444                                                                  : new GEOM_AISShape ( myShape, "" );
1445
1446       if( myType == GEOM_FIELD_STEP )
1447         AISShape->SetHilightMode( GEOM_AISShape::CustomHighlight );
1448       // update shape properties
1449       updateShapeProperties( AISShape, true );
1450
1451       // add shape to the presentation
1452       occPrs->AddObject( AISShape );
1453
1454       // In accordance with ToActivate() value object will be activated/deactivated
1455       // when it will be displayed
1456       occPrs->SetToActivate( ToActivate() );
1457
1458       if ( AISShape->isTopLevel() && GEOM_AISShape::topLevelDisplayMode() == GEOM_AISShape::TopShowAdditionalWActor ) {
1459         // 21671: EDF 1829 GEOM : Bring to front selected objects (continuation):
1460
1461         // create additional wireframe shape
1462         Handle(GEOM_TopWireframeShape) aWirePrs = new GEOM_TopWireframeShape(myShape);
1463         aWirePrs->SetWidth(AISShape->Width());
1464         if ( !myIO.IsNull() ) {
1465           aWirePrs->setIO( myIO );
1466           aWirePrs->SetOwner( myIO );
1467         }
1468
1469         // add shape to the presentation
1470         occPrs->AddObject( aWirePrs );
1471       }
1472     }
1473     // if presentation is found -> set again shape for it
1474     else
1475     {
1476       AIS_ListOfInteractive IOList;
1477       occPrs->GetObjects( IOList );
1478       AIS_ListIteratorOfListOfInteractive Iter( IOList );
1479       for ( ; Iter.More(); Iter.Next() )
1480       {
1481         Handle(GEOM_AISShape) AISShape = Handle(GEOM_AISShape)::DownCast( Iter.Value() );
1482         if ( AISShape.IsNull() )
1483           continue;
1484
1485         // re-set shape (it might be changed)
1486         if ( AISShape->Shape() != myShape )
1487           AISShape->Set( myShape );
1488
1489         // update shape properties
1490         updateShapeProperties( AISShape, false );
1491
1492         // force updating
1493         AISShape->UpdateSelection();
1494         AISShape->SetToUpdate();
1495       }
1496     }
1497
1498     updateDimensions( myIO, occPrs, gp_Ax3().Transformed( myShape.Location().Transformation() ) );
1499   }
1500 }
1501
1502 //=================================================================
1503 /*!
1504  *  GEOM_Displayer::Update
1505  *  Update VTK presentaion
1506  *  [ Reimplemented from SALOME_Displayer ]
1507  */
1508 //=================================================================
1509 void GEOM_Displayer::Update( SALOME_VTKPrs* prs )
1510 {
1511   SVTK_Prs* vtkPrs = dynamic_cast<SVTK_Prs*>( prs );
1512   SalomeApp_Study* study = getStudy();
1513
1514   if ( !vtkPrs || myShape.IsNull() || !study )
1515     return;
1516
1517   if ( myType == GEOM_MARKER && myShape.ShapeType() == TopAbs_FACE )
1518   {
1519     // 
1520     // specific processing for local coordinate system presentation
1521     // 
1522
1523     TopoDS_Face aFace = TopoDS::Face( myShape );
1524     Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( aFace ) );
1525     if ( !aPlane.IsNull() ) {
1526       gp_Ax3 aPos = aPlane->Pln().Position();
1527       Handle(Geom_Axis2Placement) aPlc = new Geom_Axis2Placement( aPos.Ax2() );
1528
1529       GEOM_VTKTrihedron* aTrh = 0;
1530
1531       if ( vtkPrs->IsNull() ) {
1532         // new presentation is being created
1533         aTrh = GEOM_VTKTrihedron::New();
1534         vtkPrs->AddObject( aTrh );
1535       }
1536       else {
1537         // presentation is being updated
1538         vtkActorCollection* actors = vtkPrs->GetObjects();
1539         if ( actors ) {
1540           actors->InitTraversal();
1541           vtkActor* a = actors->GetNextActor();
1542           while ( a && !aTrh ) {
1543             aTrh = GEOM_VTKTrihedron::SafeDownCast( a );
1544             a = actors->GetNextActor();
1545           }
1546         }
1547       }
1548       
1549       if ( aTrh ) {
1550         // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function
1551         if ( HasColor() ) {
1552           Quantity_Color aColor( (Quantity_NameOfColor)GetColor() );
1553           aTrh->SetColor( aColor.Red(), aColor.Green(), aColor.Blue() );
1554         }
1555 #ifdef VTK_TRIHEDRON_WIDTH
1556         // 
1557         // VSR: currently isn't supported
1558         //
1559         // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function 
1560         if ( HasWidth() )
1561           aTrh->SetWidth( GetWidth() );
1562 #endif
1563
1564         if ( !myIO.IsNull() )
1565           aTrh->setIO( myIO );
1566
1567         aTrh->SetPlacement( aPlc );
1568       }
1569     }
1570   }
1571   else
1572   {
1573     // 
1574     // processing for usual geometry presentation
1575     // 
1576
1577     // if presentation is empty we try to create new one
1578     if ( vtkPrs->IsNull() )
1579     {
1580       // create an actor
1581       GEOM_Actor* actor = GEOM_Actor::New();
1582       // update actor properties
1583       updateActorProperties( actor, true );
1584       // add actor to the presentation
1585       vtkPrs->AddObject( actor );
1586     }
1587     else {
1588       // presentation is being updated
1589       vtkActorCollection* actors = vtkPrs->GetObjects();
1590       if ( actors ) {
1591         actors->InitTraversal();
1592         vtkActor* a = actors->GetNextActor();
1593         while ( a ) {
1594           GEOM_Actor* actor = GEOM_Actor::SafeDownCast( a );
1595           if ( actor ) {
1596             // update actor properties
1597             updateActorProperties( actor, false );
1598             a = actors->GetNextActor();
1599           }
1600         }
1601       }
1602     }
1603   }
1604 }
1605
1606 //=================================================================
1607 /*!
1608  *  GEOM_Displayer::BuildPrs
1609  *  Build presentation accordint to the current viewer type
1610  */
1611 //=================================================================
1612 SALOME_Prs* GEOM_Displayer::BuildPrs( GEOM::GEOM_Object_ptr theObj )
1613 {
1614   if ( theObj->_is_nil() )
1615     return 0;
1616
1617   myViewFrame = GetActiveView();
1618   if ( myViewFrame == 0 )
1619     return 0;
1620
1621   SALOME_Prs* aPrs = myViewFrame->CreatePrs();
1622   if ( aPrs == 0 )
1623     return 0;
1624
1625   internalReset();
1626   setShape( GEOM_Client::get_client().GetShape( GeometryGUI::GetGeomGen(), theObj ) );
1627   myType = theObj->GetType();
1628
1629   // Update presentation
1630   UpdatePrs( aPrs );
1631
1632   return aPrs;
1633 }
1634
1635 //=================================================================
1636 /*!
1637  *  GEOM_Displayer::BuildPrs
1638  *  Build presentation accordint to the current viewer type
1639  */
1640 //=================================================================
1641 SALOME_Prs* GEOM_Displayer::BuildPrs( const TopoDS_Shape& theShape )
1642 {
1643   myViewFrame = GetActiveView();
1644   if ( theShape.IsNull() || myViewFrame == 0 )
1645     return 0;
1646
1647   SALOME_Prs* aPrs = myViewFrame->CreatePrs();
1648   if ( aPrs == 0 )
1649     return 0;
1650
1651   internalReset();
1652   setShape( theShape );
1653   myType = -1;
1654
1655   UpdatePrs( aPrs );
1656
1657   return aPrs;
1658 }
1659
1660 //=================================================================
1661 /*!
1662  *  GEOM_Displayer::buildPresentation
1663  *  Builds/finds object's presentation for the current viewer
1664  *  Calls corresponding Update() method by means of double dispatch
1665  *  [ internal ]
1666  */
1667 //=================================================================
1668 SALOME_Prs* GEOM_Displayer::buildPresentation( const QString& entry,
1669                                                SALOME_View* theViewFrame )
1670 {
1671   SALOME_Prs* prs = 0;
1672   internalReset();
1673
1674   myViewFrame = theViewFrame ? theViewFrame : GetActiveView();
1675
1676   if ( myViewFrame )
1677   {
1678     prs = LightApp_Displayer::buildPresentation( entry, theViewFrame );
1679     if ( prs )
1680     {
1681       Handle( SALOME_InteractiveObject ) theIO = new SALOME_InteractiveObject();
1682       theIO->setEntry( entry.toLatin1().constData() );
1683       if ( !theIO.IsNull() )
1684       {
1685         // set interactive object
1686         setIO( theIO );
1687         //  Find SOBject (because shape should be published previously)
1688         SUIT_Session* session = SUIT_Session::session();
1689         SUIT_Application* app = session->activeApplication();
1690         if ( app )
1691         {
1692           SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
1693           if ( study )
1694           {
1695             _PTR(SObject) SO ( study->studyDS()->FindObjectID( theIO->getEntry() ) );
1696             if ( SO )
1697             {
1698               // get CORBA reference to data object
1699               CORBA::Object_var object = GeometryGUI::ClientSObjectToObject(SO);
1700               if ( !CORBA::is_nil( object ) )
1701               {
1702                 // downcast to GEOM base object
1703                 GEOM::GEOM_BaseObject_var GeomBaseObject = GEOM::GEOM_BaseObject::_narrow( object );
1704                 if ( !GeomBaseObject->_is_nil() )
1705                 {
1706                   myType = GeomBaseObject->GetType();
1707
1708                   // downcast to GEOM object
1709                   GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
1710                   if ( myType == GEOM_FIELD_STEP )
1711                   {
1712                     // get the GEOM object from the field's shape
1713                     GEOM::GEOM_FieldStep_var GeomFieldStep = GEOM::GEOM_FieldStep::_narrow( GeomBaseObject );
1714                     if ( !GeomFieldStep->_is_nil() )
1715                     {
1716                       GEOM::GEOM_Field_var GeomField = GeomFieldStep->GetField();
1717                       if ( !GeomField->_is_nil() )
1718                         GeomObject = GeomField->GetShape();
1719                     }
1720
1721                     // read the field step information
1722                     readFieldStepInfo( GeomFieldStep );
1723                   }
1724
1725                   if ( !GeomObject->_is_nil() )
1726                   {
1727                     // finally set shape
1728                     setShape( GEOM_Client::get_client().GetShape( GeometryGUI::GetGeomGen(), GeomObject ) );
1729                   }
1730                 }
1731               }
1732             }
1733           }
1734         }
1735       }
1736       UpdatePrs( prs );  // Update presentation by using of the double dispatch
1737     }
1738   }
1739   return prs;
1740 }
1741
1742 //=================================================================
1743 /*!
1744  *  GEOM_Displayer::buildSubshapePresentation
1745  *  Builds/finds object's presentation for the current viewer
1746  *  Calls corresponding Update() method by means of double dispatch
1747  *  For not published objects (for Mantis issue 0020435)
1748  */
1749 //=================================================================
1750 SALOME_Prs* GEOM_Displayer::buildSubshapePresentation(const TopoDS_Shape& aShape,
1751                                                       const QString& entry,
1752                                                       SALOME_View* theViewFrame)
1753 {
1754   SALOME_Prs* prs = 0;
1755   internalReset();
1756
1757   myViewFrame = theViewFrame ? theViewFrame : GetActiveView();
1758
1759   if (myViewFrame)
1760   {
1761     prs = LightApp_Displayer::buildPresentation(entry, theViewFrame);
1762     if (prs)
1763     {
1764       Handle(SALOME_InteractiveObject) theIO = new SALOME_InteractiveObject();
1765       theIO->setEntry(entry.toLatin1().constData());
1766       if (!theIO.IsNull())
1767       {
1768         // set interactive object
1769         setIO(theIO);
1770         // finally set shape
1771         setShape(aShape);
1772         myType = GEOM_SUBSHAPE;
1773       }
1774       UpdatePrs(prs);  // Update presentation by using of the double dispatch
1775     }
1776   }
1777   return prs;
1778 }
1779
1780 //=================================================================
1781 /*!
1782  *  GEOM_Displayer::internalReset
1783  *  Resets internal data
1784  *  [internal]
1785  */
1786 //=================================================================
1787 void GEOM_Displayer::internalReset()
1788 {
1789   myIO.Nullify();
1790   myShape.Nullify();
1791
1792   myFieldDataType = GEOM::FDT_Double;
1793   myFieldDimension = 0;
1794   myFieldStepData.clear();
1795   myFieldStepName.Clear();
1796   myFieldStepRangeMin = 0;
1797   myFieldStepRangeMax = 0;
1798 }
1799
1800 //=================================================================
1801 /*!
1802  *  GEOM_Displayer::LocalSelection
1803  *  Activate selection of CAD shapes with activisation of selection
1804  *  of their sub-shapes (with opened local context for OCC viewer)
1805  */
1806 //=================================================================
1807 void GEOM_Displayer::LocalSelection( const Handle(SALOME_InteractiveObject)& theIO, const int theMode )
1808 {
1809   SUIT_Session* session = SUIT_Session::session();
1810   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
1811   if ( !app )
1812     return;
1813
1814   LightApp_SelectionMgr* sm = app->selectionMgr();
1815
1816   // remove all filters from selection
1817   sm->clearFilters();
1818
1819   SALOME_View* vf = GetActiveView();
1820   if ( vf ) {
1821     if (!theIO.IsNull() && !vf->isVisible(theIO))
1822       Display(theIO);
1823     SALOME_Prs* prs = vf->CreatePrs( theIO.IsNull() ? 0 : theIO->getEntry() );
1824     vf->LocalSelection( prs, theMode );
1825     delete prs;  // delete presentation because displayer is its owner
1826   }
1827 }
1828
1829 //=================================================================
1830 /*!
1831  *  GEOM_Displayer::globalSelection
1832  *  Activate selection of CAD shapes without activisation of selection
1833  *  of their sub-shapes (without opened local context for OCC viewer)
1834  */
1835 //=================================================================
1836 void GEOM_Displayer::GlobalSelection( const int theMode, const bool update )
1837 {
1838   TColStd_MapOfInteger aModes;
1839   aModes.Add( theMode );
1840   GlobalSelection( aModes, update );
1841 }
1842
1843 //=================================================================
1844 /*!
1845  *  GEOM_Displayer::globalSelection
1846  *  Activate selection of CAD shapes without activisation of selection
1847  *  of their sub-shapes (without opened local context for OCC viewer)
1848  */
1849 //=================================================================
1850 void GEOM_Displayer::GlobalSelection( const TColStd_MapOfInteger& theModes,
1851                                       const bool update, const QList<int>* theSubShapes )
1852 {
1853   SUIT_Session* session = SUIT_Session::session();
1854   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
1855   if ( !app )
1856     return;
1857
1858   SALOME_View* vf = GetActiveView();
1859   if ( vf == 0 )
1860     return;
1861
1862   // Close local context
1863   vf->GlobalSelection( update );
1864
1865   // Set selection filters in accordance with current mode
1866   LightApp_SelectionMgr* sm = app->selectionMgr();
1867   if ( !sm )
1868     return;
1869
1870   // Remove from selection temporary objects if necessary
1871   if ( !theModes.Contains( GEOM_PREVIEW ) )
1872     clearTemporary( sm );
1873
1874   //@ aSel->ClearIndex();
1875
1876   sm->clearFilters();
1877
1878   // Remove filters from AIS_InteractiveContext
1879   Handle(AIS_InteractiveContext) ic;
1880   SOCC_Viewer* viewer = dynamic_cast<SOCC_Viewer*>( vf );
1881   if ( viewer )
1882     {
1883       ic = viewer->getAISContext();
1884       if ( !ic.IsNull() )
1885         ic->RemoveFilters();
1886     }
1887
1888   if ( theModes.Contains( GEOM_ALLOBJECTS ) )
1889     return;
1890
1891   SUIT_SelectionFilter* aFilter;
1892   if ( theModes.Extent() == 1 )
1893     {
1894       int aMode = TColStd_MapIteratorOfMapOfInteger( theModes ).Key();
1895
1896       if ( aMode == GEOM_COMPOUNDFILTER )
1897         aFilter = getComplexFilter( theSubShapes );
1898       else
1899         aFilter = getFilter( aMode );
1900     }
1901   else if ( theModes.Extent() > 1 )
1902     {
1903       TColStd_MapOfInteger aTopAbsModes;
1904       TColStd_MapIteratorOfMapOfInteger anIter( theModes );
1905       QList<SUIT_SelectionFilter*> aListOfFilters;
1906       for ( ; anIter.More(); anIter.Next() )
1907         {
1908           SUIT_SelectionFilter* aFilter;
1909           int aMode = anIter.Key();
1910           if ( aMode == GEOM_COMPOUNDFILTER )
1911             aFilter = getComplexFilter( theSubShapes );
1912           else
1913             aFilter = getFilter( aMode );
1914
1915           if ( aFilter )
1916             aListOfFilters.append( aFilter );
1917         }
1918
1919       aFilter = new GEOM_LogicalFilter( aListOfFilters, GEOM_LogicalFilter::LO_OR );
1920     }
1921   else
1922     return;
1923
1924   if ( aFilter )
1925     {
1926       sm->installFilter( aFilter );
1927       if ( !ic.IsNull() )
1928         {
1929           Handle(GEOM_OCCFilter) anOCCFilter = new GEOM_OCCFilter( sm );
1930           ic->AddFilter( anOCCFilter );
1931         }
1932     }
1933 }
1934
1935 //=================================================================
1936 /*!
1937  *  GEOM_Displayer::LocalSelection
1938  *  Activate selection of CAD shapes with activisation of selection
1939  *  of their sub-shapes (with opened local context for OCC viewer)
1940  */
1941 //=================================================================
1942 void GEOM_Displayer::LocalSelection( const SALOME_ListIO& theIOList, const int theMode )
1943 {
1944   SALOME_ListIteratorOfListIO Iter( theIOList );
1945   for ( ; Iter.More(); Iter.Next() )
1946     LocalSelection( Iter.Value(), theMode );
1947 }
1948
1949 //=================================================================
1950 /*!
1951  *  GEOM_Displayer::BeforeDisplay
1952  *  Called before displaying of pars. Close local context
1953  *  [ Reimplemented from SALOME_Displayer ]
1954  */
1955 //=================================================================
1956 void GEOM_Displayer::BeforeDisplay( SALOME_View* v, const SALOME_OCCPrs* )
1957 {
1958   SOCC_Viewer* vf = dynamic_cast<SOCC_Viewer*>( v );
1959   if ( vf )
1960   {
1961     Handle(AIS_InteractiveContext) ic = vf->getAISContext();
1962     if ( !ic.IsNull() )
1963     {
1964       if ( ic->HasOpenedContext() )
1965       ic->CloseAllContexts();
1966     }
1967   }
1968 }
1969
1970 void GEOM_Displayer::AfterDisplay( SALOME_View* v, const SALOME_OCCPrs* p )
1971 {
1972   UpdateColorScale(false,false);
1973 }
1974
1975 #if OCC_VERSION_LARGE > 0x06070000
1976 void GEOM_Displayer::BeforeErase( SALOME_View* v, const SALOME_OCCPrs* p )
1977 {
1978   LightApp_Displayer::BeforeErase( v, p );
1979   releaseTextures( p );
1980 }
1981 #endif
1982
1983 void GEOM_Displayer::AfterErase( SALOME_View* v, const SALOME_OCCPrs* p )
1984 {
1985   LightApp_Displayer::AfterErase( v, p );
1986   UpdateColorScale(false,false);
1987 }
1988
1989 //=================================================================
1990 /*!
1991  *  GEOM_Displayer::SetColor
1992  *  Set color for shape displaying. If it is equal -1 then default color is used.
1993  *  Available values are from Quantity_NameOfColor enumeration
1994  */
1995 //=================================================================
1996 void GEOM_Displayer::SetColor( const int color )
1997 {
1998   if ( color == -1 )
1999     UnsetColor();
2000   else
2001   {
2002     myColor = color;
2003     myShadingColor = Quantity_Color( (Quantity_NameOfColor)color );
2004   }
2005 }
2006
2007 int GEOM_Displayer::GetColor() const
2008 {
2009   return myColor;
2010 }
2011
2012 bool GEOM_Displayer::HasColor() const
2013 {
2014   return myColor != -1;
2015 }
2016
2017 void GEOM_Displayer::UnsetColor()
2018 {
2019   myColor = -1;
2020
2021   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
2022   QColor col = resMgr->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) );
2023   myShadingColor = SalomeApp_Tools::color( col );
2024 }
2025
2026 //=================================================================
2027 /*!
2028  *  GEOM_Displayer::SetTransparency
2029  *  Set transparency for shape displaying.
2030  */
2031 //=================================================================
2032 double GEOM_Displayer::SetTransparency( const double transparency )
2033 {
2034   double aPrevTransparency = myTransparency;
2035   if ( transparency < 0 ) {
2036     UnsetTransparency();
2037   }
2038   else {
2039     myTransparency = transparency;
2040     myHasTransparency = true;
2041   }
2042   return aPrevTransparency;
2043 }
2044
2045 //=================================================================
2046 /*!
2047  *  GEOM_Displayer::GetTransparency
2048  *  Get transparency for shape displaying.
2049  */
2050 //=================================================================
2051 double GEOM_Displayer::GetTransparency() const
2052 {
2053   return myTransparency;
2054 }
2055
2056 //=================================================================
2057 /*!
2058  *  GEOM_Displayer::HasTransparency
2059  *  Check if transparency for shape displaying is set.
2060  */
2061 //=================================================================
2062 bool GEOM_Displayer::HasTransparency() const
2063 {
2064   return myHasTransparency;
2065 }
2066
2067 //=================================================================
2068 /*!
2069  *  GEOM_Displayer::UnsetTransparency
2070  *  Unset transparency for shape displaying.
2071  */
2072 //=================================================================
2073 double GEOM_Displayer::UnsetTransparency()
2074 {
2075   double aPrevTransparency = myTransparency;
2076   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
2077   myTransparency = resMgr->integerValue("Geometry", "transparency", 0) / 100.;
2078   myHasTransparency = false;
2079   return aPrevTransparency;
2080 }
2081
2082
2083 //=================================================================
2084 /*!
2085  *  GEOM_Displayer::SetTexture
2086  *  Set color for shape displaying. If it is equal -1 then default color is used.
2087  *  Available values are from Quantity_NameOfColor enumeration
2088  */
2089 //=================================================================
2090 void GEOM_Displayer::SetTexture( const std::string& texureFileName )
2091 {
2092   if(texureFileName!="")
2093   {
2094     myTexture = texureFileName;
2095   }
2096 }
2097
2098 bool GEOM_Displayer::HasTexture() const
2099 {
2100   return myTexture != "";
2101 }
2102
2103 std::string GEOM_Displayer::GetTexture() const
2104 {
2105   return myTexture;
2106 }
2107
2108 //=================================================================
2109 /*!
2110  *  GEOM_Displayer::SetWidth
2111  *  Set width of shape displaying. If it is equal -1 then default width is used.
2112  */
2113 //=================================================================
2114 void GEOM_Displayer::SetWidth( const double width )
2115 {
2116   myWidth = width;
2117 }
2118
2119 double GEOM_Displayer::GetWidth() const
2120 {
2121   return myWidth;
2122 }
2123
2124 bool GEOM_Displayer::HasWidth() const
2125 {
2126   return myWidth != -1;
2127 }
2128
2129 void GEOM_Displayer::UnsetWidth()
2130 {
2131   myWidth = -1;
2132 }
2133
2134
2135 int GEOM_Displayer::GetIsosWidth() const
2136 {
2137   return myIsosWidth;
2138 }
2139
2140 void GEOM_Displayer::SetIsosWidth(const int width)
2141 {
2142   myIsosWidth = width;
2143 }
2144
2145 bool GEOM_Displayer::HasIsosWidth() const
2146 {
2147   return myIsosWidth != -1;
2148 }
2149
2150
2151 //=================================================================
2152 /*!
2153  *  GEOM_Displayer::SetToActivate
2154  *  This method is used for activisation/deactivisation of objects to be displayed
2155  */
2156 //=================================================================
2157 void GEOM_Displayer::SetToActivate( const bool toActivate )
2158 {
2159   myToActivate = toActivate;
2160 }
2161 bool GEOM_Displayer::ToActivate() const
2162 {
2163   return myToActivate;
2164 }
2165
2166 //=================================================================
2167 /*!
2168  *  GEOM_Displayer::clearTemporary
2169  *  Removes from selection temporary objects
2170  */
2171 //=================================================================
2172 void GEOM_Displayer::clearTemporary( LightApp_SelectionMgr* theSelMgr )
2173 {
2174   SALOME_ListIO selected, toSelect;
2175   theSelMgr->selectedObjects( selected );
2176
2177   for (  SALOME_ListIteratorOfListIO it( selected ) ; it.More(); it.Next() ) {
2178     Handle(SALOME_InteractiveObject) io = it.Value();
2179     if ( !io.IsNull() && io->hasEntry() && strncmp( io->getEntry(), "TEMP_", 5 ) != 0 )
2180       toSelect.Append( it.Value() );
2181   }
2182
2183   theSelMgr->setSelectedObjects( toSelect, true );
2184 }
2185
2186 void GEOM_Displayer::SetName( const char* theName )
2187 {
2188   myName = theName;
2189 }
2190
2191 void GEOM_Displayer::UnsetName()
2192 {
2193   myName = "";
2194 }
2195
2196 SalomeApp_Study* GEOM_Displayer::getStudy() const
2197 {
2198   return dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
2199 }
2200
2201 void GEOM_Displayer::setIO( const Handle(SALOME_InteractiveObject)& theIO )
2202 {
2203   myIO = theIO;
2204 }
2205
2206 void GEOM_Displayer::setShape( const TopoDS_Shape& theShape )
2207 {
2208   myShape = theShape;
2209 }
2210
2211 void GEOM_Displayer::setFieldStepInfo( const GEOM::field_data_type theFieldDataType,
2212                                        const int theFieldDimension,
2213                                        const QList<QVariant>& theFieldStepData,
2214                                        const TCollection_AsciiString& theFieldStepName,
2215                                        const double theFieldStepRangeMin,
2216                                        const double theFieldStepRangeMax )
2217 {
2218   myFieldDataType = theFieldDataType;
2219   myFieldDimension = theFieldDimension;
2220   myFieldStepData = theFieldStepData;
2221   myFieldStepName = theFieldStepName;
2222   myFieldStepRangeMin = theFieldStepRangeMin;
2223   myFieldStepRangeMax = theFieldStepRangeMax;
2224 }
2225
2226 bool GEOM_Displayer::canBeDisplayed( const QString& entry, const QString& viewer_type ) const
2227 {
2228   _PTR(SObject) anObj = getStudy()->studyDS()->FindObjectID( (const char*)entry.toLatin1() );
2229   GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(anObj)); // enable displaying of GEOM objects
2230   GEOM::GEOM_FieldStep_var aFieldStepObj = GEOM::GEOM_FieldStep::_narrow(GeometryGUI::ClientSObjectToObject(anObj)); // enable displaying of GEOM field steps
2231   GEOM::GEOM_Gen_var aCompObj = GEOM::GEOM_Gen::_narrow(GeometryGUI::ClientSObjectToObject(anObj)); // enable displaying of whole GEOM component
2232   return ( !CORBA::is_nil( aGeomObj ) || !CORBA::is_nil( aFieldStepObj ) || !CORBA::is_nil( aCompObj ) ) &&
2233          (viewer_type == SOCC_Viewer::Type() || viewer_type == SVTK_Viewer::Type());
2234 }
2235
2236 int GEOM_Displayer::SetDisplayMode( const int theMode )
2237 {
2238   int aPrevMode = myDisplayMode;
2239   if ( theMode != -1 ) {
2240     myDisplayMode = theMode;
2241     myHasDisplayMode = true;
2242   }
2243   else {
2244     UnsetDisplayMode();
2245   }
2246   return aPrevMode;
2247 }
2248
2249 int GEOM_Displayer::GetDisplayMode() const
2250 {
2251   return myDisplayMode;
2252 }
2253
2254 int GEOM_Displayer::UnsetDisplayMode()
2255 {
2256   int aPrevMode = myDisplayMode;
2257   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
2258   myDisplayMode = resMgr->integerValue( "Geometry", "display_mode", 0 );
2259   myHasDisplayMode = false;
2260   return aPrevMode;
2261 }
2262
2263 bool GEOM_Displayer::HasDisplayMode() const
2264 {
2265   return myHasDisplayMode;
2266 }
2267
2268 SALOMEDS::Color GEOM_Displayer::getPredefinedUniqueColor()
2269 {
2270   static QList<QColor> colors;
2271
2272   if ( colors.isEmpty() ) {
2273
2274     for (int s = 0; s < 2 ; s++)
2275     {
2276       for (int v = 100; v >= 40; v = v - 20)
2277       {
2278         for (int h = 0; h < 359 ; h = h + 60)
2279         {
2280           colors.append(QColor::fromHsv(h, 255 - s * 127, v * 255 / 100));
2281         }
2282       }
2283     }
2284   }
2285
2286   static int currentColor = 0;
2287
2288   SALOMEDS::Color color;
2289   color.R = (double)colors[currentColor].red()   / 255.0;
2290   color.G = (double)colors[currentColor].green() / 255.0;
2291   color.B = (double)colors[currentColor].blue()  / 255.0;
2292
2293   currentColor = (currentColor+1) % colors.count();
2294
2295   return color;
2296 }
2297
2298 SALOMEDS::Color GEOM_Displayer::getUniqueColor( const QList<SALOMEDS::Color>& theReservedColors )
2299 {
2300   int aHue = -1;
2301   int aTolerance = 64;
2302   int anIterations = 0;
2303   int aPeriod = 5;
2304
2305   while( 1 )
2306   {
2307     anIterations++;
2308     if( anIterations % aPeriod == 0 )
2309     {
2310       aTolerance /= 2;
2311       if( aTolerance < 1 )
2312         break;
2313     }
2314     //std::cout << "Iteration N" << anIterations << " (tolerance=" << aTolerance << ")"<< std::endl;
2315
2316     aHue = (int)( 360.0 * rand() / RAND_MAX );
2317     //std::cout << "Hue = " << aHue << std::endl;
2318
2319     //std::cout << "Auto colors : ";
2320     bool ok = true;
2321     QList<SALOMEDS::Color>::const_iterator it = theReservedColors.constBegin();
2322     QList<SALOMEDS::Color>::const_iterator itEnd = theReservedColors.constEnd();
2323     for( ; it != itEnd; ++it )
2324     {
2325       SALOMEDS::Color anAutoColor = *it;
2326       QColor aQColor( (int)( anAutoColor.R * 255.0 ), (int)( anAutoColor.G * 255.0 ), (int)( anAutoColor.B * 255.0 ) );
2327
2328       int h, s, v;
2329       aQColor.getHsv( &h, &s, &v );
2330       //std::cout << h << " ";
2331       if( abs( h - aHue ) < aTolerance )
2332       {
2333         ok = false;
2334         //std::cout << "break (diff = " << abs( h - aHue ) << ")";
2335         break;
2336       }
2337     }
2338     //std::cout << std::endl;
2339
2340     if( ok )
2341       break;
2342   }
2343
2344   //std::cout << "Hue of the returned color = " << aHue << std::endl;
2345   QColor aColor;
2346   aColor.setHsv( aHue, 255, 255 );
2347
2348   SALOMEDS::Color aSColor;
2349   aSColor.R = (double)aColor.red() / 255.0;
2350   aSColor.G = (double)aColor.green() / 255.0;
2351   aSColor.B = (double)aColor.blue() / 255.0;
2352
2353   return aSColor;
2354 }
2355
2356 PropMap GEOM_Displayer::getObjectProperties( SalomeApp_Study* study,
2357                                              const QString& entry,
2358                                              SALOME_View* view )
2359 {
2360   // get default properties for the explicitly specified default view type
2361   PropMap propMap = GEOM_Displayer::getDefaultPropertyMap();
2362
2363   if ( study && view ) {
2364     SUIT_ViewModel* viewModel = dynamic_cast<SUIT_ViewModel*>( view );
2365     SUIT_ViewManager* viewMgr = ( viewModel != 0 ) ? viewModel->getViewManager() : 0;
2366     int viewId = ( viewMgr != 0 ) ? viewMgr->getGlobalId() : -1;
2367   
2368     if ( viewModel && viewId != -1 ) {
2369       // get properties from the study
2370       PropMap storedMap = study->getObjectPropMap( viewId, entry );
2371       // overwrite default properties from stored ones (that are specified)
2372       for ( int prop = GEOM::Visibility; prop <= GEOM::LastProperty; prop++ ) {
2373         if ( storedMap.contains( GEOM::propertyName( (GEOM::Property)prop ) ) )
2374           propMap.insert( GEOM::propertyName( (GEOM::Property)prop ), 
2375                           storedMap.value( GEOM::propertyName( (GEOM::Property)prop ) ) );
2376       }
2377       // ... specific processing for color
2378       // ... current implementation is to use same stored color for all aspects
2379       // ... (TODO) possible future improvements about free boundaries, standalone edges etc colors can be here
2380       if ( storedMap.contains( GEOM::propertyName( GEOM::Color ) ) ) {
2381         propMap.insert( GEOM::propertyName( GEOM::ShadingColor ),   storedMap.value( GEOM::propertyName( GEOM::Color ) ) );
2382         propMap.insert( GEOM::propertyName( GEOM::WireframeColor ), storedMap.value( GEOM::propertyName( GEOM::Color ) ) );
2383         propMap.insert( GEOM::propertyName( GEOM::LineColor ),      storedMap.value( GEOM::propertyName( GEOM::Color ) ) );
2384         propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ),   storedMap.value( GEOM::propertyName( GEOM::Color ) ) );
2385         propMap.insert( GEOM::propertyName( GEOM::PointColor ),     storedMap.value( GEOM::propertyName( GEOM::Color ) ) );
2386       }
2387
2388       if ( !entry.isEmpty() ) {
2389         // get CORBA reference to geom object
2390         _PTR(SObject) SO( study->studyDS()->FindObjectID( entry.toStdString() ) );
2391         if ( SO ) {
2392           CORBA::Object_var object = GeometryGUI::ClientSObjectToObject( SO );
2393           if ( !CORBA::is_nil( object ) ) {
2394             GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_narrow( object );
2395             if ( !CORBA::is_nil( geomObject ) ) { // to check
2396               // check that geom object has color properly set
2397               bool hasColor = false;
2398               SALOMEDS::Color aSColor = getColor( geomObject, hasColor );
2399               // set color from geometry object (only once, if it is not yet set in GUI)
2400               // current implementation is to use same color for all aspects
2401               // (TODO) possible future improvements about free boundaries, standalone edges etc colors can be here
2402               if ( hasColor && !storedMap.contains( GEOM::propertyName( GEOM::Color ) ) ) {
2403                 QColor objColor = QColor::fromRgbF( aSColor.R, aSColor.G, aSColor.B );
2404                 propMap.insert( GEOM::propertyName( GEOM::ShadingColor ),   objColor );
2405                 propMap.insert( GEOM::propertyName( GEOM::WireframeColor ), objColor );
2406                 propMap.insert( GEOM::propertyName( GEOM::LineColor ),      objColor );
2407                 propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ),   objColor );
2408                 propMap.insert( GEOM::propertyName( GEOM::PointColor ),     objColor );
2409               }
2410               // check that object has point marker properly set
2411               GEOM::marker_type mType = geomObject->GetMarkerType();
2412               GEOM::marker_size mSize = geomObject->GetMarkerSize();
2413               int mTextureId = geomObject->GetMarkerTexture();
2414               bool hasMarker = ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER && mSize > GEOM::MS_NONE && mSize <= GEOM::MS_70 ) || 
2415                                ( mType == GEOM::MT_USER && mTextureId > 0 );
2416               // set point marker from geometry object (only once, if it is not yet set in GUI)
2417               if ( hasMarker && !storedMap.contains( GEOM::propertyName( GEOM::PointMarker ) ) ) {
2418                 if ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER ) {
2419                   // standard type
2420                   propMap.insert( GEOM::propertyName( GEOM::PointMarker ),
2421                                   QString( "%1%2%3" ).arg( (int)mType ).arg( GEOM::subSectionSeparator() ).arg( (int)mSize ) );
2422                 }
2423                 else if ( mType == GEOM::MT_USER ) {
2424                   // custom texture
2425                   propMap.insert( GEOM::propertyName( GEOM::PointMarker ), QString::number( mTextureId ) );
2426                 }
2427               }
2428             }
2429           }
2430         }
2431       }
2432     }
2433   }
2434   return propMap;
2435 }
2436
2437 PropMap GEOM_Displayer::getDefaultPropertyMap()
2438 {
2439   PropMap propMap;
2440
2441   // get resource manager
2442   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
2443
2444   // fill in the properties map with default values
2445
2446   // - visibility (false by default)
2447   propMap.insert( GEOM::propertyName( GEOM::Visibility ), false );
2448
2449   // - nb isos (take default value from preferences)
2450   propMap.insert( GEOM::propertyName( GEOM::NbIsos ),
2451                   QString( "%1%2%3" ).
2452                   arg( resMgr->integerValue( "Geometry", "iso_number_u", 1 ) ).
2453                   arg( GEOM::subSectionSeparator() ).
2454                   arg( resMgr->integerValue( "Geometry", "iso_number_v", 1 ) ) );
2455
2456   // - transparency (opacity = 1-transparency)
2457   propMap.insert( GEOM::propertyName( GEOM::Transparency ),
2458                   resMgr->integerValue( "Geometry", "transparency", 0 ) / 100. );
2459
2460   // - display mode (take default value from preferences)
2461   propMap.insert( GEOM::propertyName( GEOM::DisplayMode ),
2462                   resMgr->integerValue( "Geometry", "display_mode", 0 ) );
2463
2464   // - show edges direction flag (false by default)
2465   propMap.insert( GEOM::propertyName( GEOM::EdgesDirection ), false );
2466
2467   // - show vertices flag (false by default)
2468   propMap.insert( GEOM::propertyName( GEOM::Vertices ), false );
2469
2470   // - shading color (take default value from preferences)
2471   propMap.insert( GEOM::propertyName( GEOM::ShadingColor ),
2472                   colorFromResources( "shading_color", QColor( 255, 255, 0 ) ) );
2473
2474   // - wireframe color (take default value from preferences)
2475   propMap.insert( GEOM::propertyName( GEOM::WireframeColor ),
2476                   colorFromResources( "wireframe_color", QColor( 255, 255, 0 ) ) );
2477
2478   // - standalone edges color (take default value from preferences)
2479   propMap.insert( GEOM::propertyName( GEOM::LineColor ),
2480                   colorFromResources( "line_color", QColor( 255, 0, 0 ) ) );
2481
2482   // - free boundaries color (take default value from preferences)
2483   propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ),
2484                   colorFromResources( "free_bound_color", QColor( 0, 255, 0 ) ) );
2485
2486   // - points color (take default value from preferences)
2487   propMap.insert( GEOM::propertyName( GEOM::PointColor ),
2488                   colorFromResources( "point_color", QColor( 255, 255, 0 ) ) );
2489
2490   // - isos color (take default value from preferences)
2491   propMap.insert( GEOM::propertyName( GEOM::IsosColor ),
2492                   colorFromResources( "isos_color", QColor( 200, 200, 200 ) ) );
2493
2494   // - outlines color (take default value from preferences)
2495   propMap.insert( GEOM::propertyName( GEOM::OutlineColor ),
2496                   colorFromResources( "edges_in_shading_color", QColor( 180, 180, 180 ) ) );
2497
2498   // - deflection coefficient (take default value from preferences)
2499   propMap.insert( GEOM::propertyName( GEOM::Deflection ),
2500                   resMgr->doubleValue( "Geometry", "deflection_coeff", 0.001 ) );
2501
2502   // - material (take default value from preferences)
2503   Material_Model material;
2504   material.fromResources( resMgr->stringValue( "Geometry", "material", "Plastic" ) );
2505   propMap.insert( GEOM::propertyName( GEOM::Material ), material.toProperties() );
2506
2507   // - edge width (take default value from preferences)
2508   propMap.insert( GEOM::propertyName( GEOM::LineWidth ),
2509                   resMgr->integerValue( "Geometry", "edge_width", 1 ) );
2510
2511   // - isos width (take default value from preferences)
2512   propMap.insert( GEOM::propertyName( GEOM::IsosWidth ),
2513                   resMgr->integerValue( "Geometry", "isolines_width", 1 ) );
2514
2515   // - point marker (take default value from preferences)
2516   propMap.insert( GEOM::propertyName( GEOM::PointMarker ),
2517                   QString( "%1%2%3" ).
2518                   arg( resMgr->integerValue( "Geometry", "type_of_marker", 1 ) + 1 ).
2519                   arg( GEOM::subSectionSeparator() ).
2520                   arg( resMgr->integerValue( "Geometry", "marker_scale", 1 ) ) );
2521
2522   // - top-level flag (false by default)
2523   propMap.insert( GEOM::propertyName( GEOM::TopLevel ), false );
2524
2525   return propMap;
2526 }
2527
2528 SALOMEDS::Color GEOM_Displayer::getColor(GEOM::GEOM_Object_var theGeomObject, bool& hasColor) {
2529   SALOMEDS::Color aSColor;
2530   hasColor = false;
2531
2532   SUIT_Session* session = SUIT_Session::session();
2533   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
2534
2535   if ( app && !theGeomObject->_is_nil()) {
2536     SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
2537
2538     if ( study ) {
2539       _PTR(Study) aStudy = study->studyDS();
2540       aSColor = theGeomObject->GetColor();
2541       hasColor = aSColor.R >= 0 && aSColor.G >= 0 && aSColor.B >= 0;
2542       if ( !hasColor ) {
2543 #ifdef GENERAL_AUTOCOLOR // auto-color for all sub-shapes
2544         bool general_autocolor = true;
2545 #else                    // auto-color for groups only
2546         bool general_autocolor = false;
2547 #endif                   // GENERAL_AUTOCOLOR
2548         if ( general_autocolor || theGeomObject->GetType() == GEOM_GROUP ) {
2549           GEOM::GEOM_Object_var aMainObject = theGeomObject->GetMainShape();
2550           if ( !CORBA::is_nil( aMainObject ) && aMainObject->GetAutoColor() ) {
2551 #ifdef SIMPLE_AUTOCOLOR  // simplified algorithm for auto-colors
2552             aSColor = getPredefinedUniqueColor();
2553             hasColor = true;
2554 #else                    // old algorithm  for auto-colors
2555             QList<SALOMEDS::Color> aReservedColors;
2556             CORBA::String_var IOR = app->orb()->object_to_string( aMainObject );
2557             _PTR(SObject) aMainSObject( aStudy->FindObjectIOR( IOR.in() ) );
2558             if ( aMainSObject ) {
2559               _PTR(ChildIterator) it( aStudy->NewChildIterator( aMainSObject ) );
2560               for ( ; it->More(); it->Next() ) {
2561                 _PTR(SObject) aChildSObject( it->Value() );
2562                 GEOM::GEOM_Object_var aChildObject =
2563                   GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aChildSObject));
2564                 if ( CORBA::is_nil( aChildObject ) )
2565                   continue;
2566
2567                 SALOMEDS::Color aReservedColor = aChildObject->GetColor();
2568                 if ( aReservedColor.R >= 0 && aReservedColor.G >= 0 && aReservedColor.B >= 0 )
2569                   aReservedColors.append( aReservedColor );
2570               }
2571             }
2572             aSColor = getUniqueColor( aReservedColors );
2573             hasColor = true;
2574 #endif                   // SIMPLE_AUTOCOLOR
2575           }
2576         }
2577       }
2578     }
2579   }
2580   return aSColor;
2581 }
2582
2583
2584 void GEOM_Displayer::EraseWithChildren(const Handle(SALOME_InteractiveObject)& theIO,
2585                                        const bool eraseOnlyChildren) {
2586   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
2587   if ( !app )
2588     return;
2589
2590   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
2591   if ( !appStudy )
2592     return;
2593
2594   LightApp_DataObject* parent = appStudy->findObjectByEntry(theIO->getEntry());
2595
2596   if( !parent)
2597     return;
2598
2599   // Erase from all views
2600   QList<SALOME_View*> views;
2601   SALOME_View* view;
2602   ViewManagerList vmans = app->viewManagers();
2603   SUIT_ViewManager* vman;
2604   foreach ( vman, vmans ) {
2605     SUIT_ViewModel* vmod = vman->getViewModel();
2606     view = dynamic_cast<SALOME_View*> ( vmod );
2607     if ( view )
2608       views.append( view );
2609   }
2610
2611   if( views.count() == 0 )
2612     return;
2613
2614   //Erase childrens w/o update views
2615   DataObjectList listObj = parent->children( true );
2616   SUIT_DataObject* obj;
2617   foreach( obj, listObj ) {
2618     LightApp_DataObject* l_obj = dynamic_cast<LightApp_DataObject*>(obj);
2619     if(l_obj)
2620       foreach ( view, views ) {
2621       Handle(SALOME_InteractiveObject) anIO =
2622         new SALOME_InteractiveObject(qPrintable(l_obj->entry()), "GEOM", "");
2623       Erase(anIO, false, false, view);
2624     }
2625   }
2626
2627   //Erase parent with view update or repaint views
2628   foreach ( view, views ) {
2629     if(!eraseOnlyChildren)
2630       Erase(theIO, false, true, view);
2631     else
2632       view->Repaint();
2633   }
2634 }
2635
2636 void GEOM_Displayer::readFieldStepInfo( GEOM::GEOM_FieldStep_var theGeomFieldStep )
2637 {
2638   if( theGeomFieldStep->_is_nil() )
2639     return;
2640
2641   GEOM::GEOM_Field_var aGeomField = theGeomFieldStep->GetField();
2642   if( aGeomField->_is_nil() )
2643     return;
2644
2645   GEOM::GEOM_Object_var aGeomFieldShape = aGeomField->GetShape();
2646   if( aGeomFieldShape->_is_nil() )
2647     return;
2648
2649   TCollection_AsciiString aFieldStepName( theGeomFieldStep->GetName() );
2650   TCollection_AsciiString aFieldName( aGeomField->GetName() );
2651   TCollection_AsciiString aShapeName( aGeomFieldShape->GetName() );
2652
2653   aFieldStepName = aShapeName + "\n" + aFieldName + "\n" + aFieldStepName;
2654
2655   GEOM::field_data_type aFieldDataType = aGeomField->GetDataType();
2656
2657   int aFieldDimension = aGeomField->GetDimension();
2658
2659   GEOM::string_array_var aFieldComponents = aGeomField->GetComponents();
2660   int aFieldNbComponents = aFieldComponents->length();
2661
2662   QList<QVariant> aFieldStepData;
2663   if( aFieldDataType == GEOM::FDT_Bool )
2664   {
2665     GEOM::GEOM_BoolFieldStep_var aGeomBoolFieldStep = GEOM::GEOM_BoolFieldStep::_narrow( theGeomFieldStep );
2666     if ( !aGeomBoolFieldStep->_is_nil() )
2667     {
2668       GEOM::short_array_var aValues = aGeomBoolFieldStep->GetValues();
2669       for( size_t i = 0, n = aValues->length(); i < n; i++ )
2670         aFieldStepData << (bool)aValues[i];
2671     }
2672   }
2673   else if( aFieldDataType == GEOM::FDT_Int )
2674   {
2675     GEOM::GEOM_IntFieldStep_var aGeomIntFieldStep = GEOM::GEOM_IntFieldStep::_narrow( theGeomFieldStep );
2676     if ( !aGeomIntFieldStep->_is_nil() )
2677     {
2678       GEOM::ListOfLong_var aValues = aGeomIntFieldStep->GetValues();
2679       for( size_t i = 0, n = aValues->length(); i < n; i++ )
2680         aFieldStepData << (qlonglong)aValues[i];
2681     }
2682   }
2683   else if( aFieldDataType == GEOM::FDT_Double )
2684   {
2685     GEOM::GEOM_DoubleFieldStep_var aGeomDoubleFieldStep = GEOM::GEOM_DoubleFieldStep::_narrow( theGeomFieldStep );
2686     if ( !aGeomDoubleFieldStep->_is_nil() )
2687     {
2688       GEOM::ListOfDouble_var aValues = aGeomDoubleFieldStep->GetValues();
2689       for( size_t i = 0, n = aValues->length(); i < n; i++ )
2690         aFieldStepData << (double)aValues[i];
2691     }
2692   }
2693   else if( aFieldDataType == GEOM::FDT_String )
2694   {
2695     GEOM::GEOM_StringFieldStep_var aGeomStringFieldStep = GEOM::GEOM_StringFieldStep::_narrow( theGeomFieldStep );
2696     if ( !aGeomStringFieldStep->_is_nil() )
2697     {
2698       GEOM::string_array_var aValues = aGeomStringFieldStep->GetValues();
2699       for( size_t i = 0, n = aValues->length(); i < n; i++ )
2700         aFieldStepData << QString( aValues[i] );
2701     }
2702   }
2703
2704   double aFieldStepRangeMin = 0, aFieldStepRangeMax = 0;
2705   aFieldStepData = groupFieldData( aFieldStepData,
2706                                    aFieldNbComponents,
2707                                    aFieldDataType == GEOM::FDT_String,
2708                                    aFieldStepRangeMin,
2709                                    aFieldStepRangeMax );
2710
2711   setFieldStepInfo( aFieldDataType,
2712                     aFieldDimension,
2713                     aFieldStepData,
2714                     aFieldStepName,
2715                     aFieldStepRangeMin,
2716                     aFieldStepRangeMax );
2717 }
2718
2719 QList<QVariant> GEOM_Displayer::groupFieldData( const QList<QVariant>& theFieldStepData,
2720                                                 const int theFieldNbComponents,
2721                                                 const bool theIsString,
2722                                                 double& theFieldStepRangeMin,
2723                                                 double& theFieldStepRangeMax )
2724 {
2725   QList<QVariant> aResultList;
2726   theFieldStepRangeMin = 0;
2727   theFieldStepRangeMax = 0;
2728
2729   if( theFieldStepData.isEmpty() || theFieldNbComponents < 1 )
2730     return aResultList;
2731
2732   int aNbSubShapes = theFieldStepData.count() / theFieldNbComponents;
2733
2734   QList<QVariant> aGroupedList;
2735
2736   bool anIsBoolean = false;
2737   for( int aSubShape = 0; aSubShape < aNbSubShapes; aSubShape++ )
2738   {
2739     double aNorm = 0;
2740     QStringList aStringList;
2741
2742     int aBaseIndex = aSubShape * theFieldNbComponents;
2743     for( int aComponent = 0; aComponent < theFieldNbComponents; aComponent++ )
2744     {
2745       int anIndex = aComponent + aBaseIndex;
2746
2747       const QVariant& aVariant = theFieldStepData[ anIndex ];
2748       if( theIsString )
2749       {
2750         if( aVariant.type() == QVariant::String )
2751           aStringList << aVariant.toString();
2752       }
2753       else
2754       {
2755         double aValue = 0;
2756         if( aVariant.type() == QVariant::Bool )
2757         {
2758           aValue = aVariant.toBool() ? 1.0 : 0.0;
2759           aNorm += aValue;
2760           anIsBoolean = true;
2761         }
2762         else
2763         {
2764           if( aVariant.type() == QVariant::LongLong )
2765             aValue = double( aVariant.toLongLong() );
2766           else if( aVariant.type() == QVariant::Double )
2767             aValue = aVariant.toDouble();
2768           aNorm += aValue * aValue;
2769         }
2770       }
2771     }
2772
2773     if( theIsString )
2774       aGroupedList << aStringList.join( "\n" );
2775     else
2776     {
2777       if( anIsBoolean )
2778         aNorm /= theFieldNbComponents;
2779       else
2780         aNorm = pow( aNorm, 0.5 );
2781
2782       if( aGroupedList.isEmpty() )
2783         theFieldStepRangeMin = theFieldStepRangeMax = aNorm;
2784       else
2785       {
2786         theFieldStepRangeMin = Min( theFieldStepRangeMin, aNorm );
2787         theFieldStepRangeMax = Max( theFieldStepRangeMax, aNorm );
2788       }
2789
2790       aGroupedList << aNorm;
2791     }
2792   }
2793
2794   if( anIsBoolean )
2795   {
2796     theFieldStepRangeMin = 0.0;
2797     theFieldStepRangeMax = 1.0;
2798   }
2799
2800   SUIT_Session* session = SUIT_Session::session();
2801   SUIT_ResourceMgr* resMgr = session->resourceMgr();
2802   Standard_Integer aNbIntervals = resMgr->integerValue( "Geometry", "scalar_bar_nb_intervals", 20 );
2803
2804   QListIterator<QVariant> anIter( aGroupedList );
2805   while( anIter.hasNext() )
2806   {
2807     const QVariant& aVariant = anIter.next();
2808     if( theIsString )
2809       aResultList << aVariant;
2810     else
2811     {
2812       QColor aQColor;
2813       Quantity_Color aColor;
2814       if( FindColor( aVariant.toDouble(), theFieldStepRangeMin, theFieldStepRangeMax, anIsBoolean ? 2 : aNbIntervals, aColor ) )
2815         aQColor = QColor::fromRgbF( aColor.Red(), aColor.Green(), aColor.Blue() );
2816       aResultList << aQColor;
2817     }
2818   }
2819   return aResultList;
2820 }
2821
2822 // Note: the method is copied from Aspect_ColorScale class
2823 Standard_Integer GEOM_Displayer::HueFromValue( const Standard_Integer aValue,
2824                                                const Standard_Integer aMin,
2825                                                const Standard_Integer aMax )
2826 {
2827   Standard_Integer minLimit( 0 ), maxLimit( 230 );
2828
2829   Standard_Integer aHue = maxLimit;
2830   if ( aMin != aMax )
2831     aHue = (Standard_Integer)( maxLimit - ( maxLimit - minLimit ) * ( aValue - aMin ) / ( aMax - aMin ) );
2832
2833   aHue = Min( Max( minLimit, aHue ), maxLimit );
2834
2835   return aHue;
2836 }
2837
2838 // Note: the method is copied from Aspect_ColorScale class
2839 Standard_Boolean GEOM_Displayer::FindColor( const Standard_Real aValue, 
2840                                             const Standard_Real aMin,
2841                                             const Standard_Real aMax,
2842                                             const Standard_Integer ColorsCount,
2843                                             Quantity_Color& aColor )
2844 {
2845   if( aValue<aMin || aValue>aMax || aMax<aMin )
2846     return Standard_False;
2847
2848   else
2849   {
2850     Standard_Real IntervNumber = 0;
2851     if( aValue<aMin )
2852       IntervNumber = 0;
2853     else if( aValue>aMax )
2854       IntervNumber = ColorsCount-1;
2855     else if( Abs( aMax-aMin ) > Precision::Approximation() )
2856       IntervNumber = Floor( Standard_Real( ColorsCount ) * ( aValue - aMin ) / ( aMax - aMin ) ); // 'Ceiling' replaced with 'Floor'
2857
2858     Standard_Integer Interv = Standard_Integer( IntervNumber );
2859
2860     aColor = Quantity_Color( HueFromValue( Interv, 0, ColorsCount - 1 ), 1.0, 1.0, Quantity_TOC_HLS );
2861
2862     return Standard_True;
2863   } 
2864 }
2865
2866 void GEOM_Displayer::UpdateColorScale( const bool theIsRedisplayFieldSteps, const bool updateViewer ) 
2867 {
2868   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
2869   if( !aStudy )
2870     return;
2871
2872   SOCC_Viewer* aViewModel = dynamic_cast<SOCC_Viewer*>( GetActiveView() );
2873   if( !aViewModel )
2874     return;
2875
2876   Handle(V3d_Viewer) aViewer = aViewModel->getViewer3d();
2877   if( aViewer.IsNull() )
2878     return;
2879
2880   aViewer->InitActiveViews();
2881   if( !aViewer->MoreActiveViews() )
2882     return;
2883
2884   Handle(V3d_View) aView = aViewer->ActiveView();
2885   if( aView.IsNull() )
2886     return;
2887
2888   Standard_Boolean anIsDisplayColorScale = Standard_False;
2889   TCollection_AsciiString aColorScaleTitle;
2890   Standard_Real aColorScaleMin = 0, aColorScaleMax = 0;
2891   Standard_Boolean anIsBoolean = Standard_False;
2892
2893   SALOME_ListIO aSelectedObjects;
2894   myApp->selectionMgr()->selectedObjects( aSelectedObjects );
2895   if( aSelectedObjects.Extent() == 1 )
2896   {
2897     Handle(SALOME_InteractiveObject) anIO = aSelectedObjects.First();
2898     if( !anIO.IsNull() )
2899     {
2900       SOCC_Prs* aPrs = dynamic_cast<SOCC_Prs*>( aViewModel->CreatePrs( anIO->getEntry() ) );
2901       if( aPrs )
2902       {
2903         AIS_ListOfInteractive aList;
2904         aPrs->GetObjects( aList );
2905         AIS_ListIteratorOfListOfInteractive anIter( aList );
2906         for( ; anIter.More(); anIter.Next() )
2907         {
2908           Handle(GEOM_AISShape) aShape = Handle(GEOM_AISShape)::DownCast( anIter.Value() );
2909           if( !aShape.IsNull() )
2910           {
2911             GEOM::field_data_type aFieldDataType;
2912             int aFieldDimension;
2913             QList<QVariant> aFieldStepData;
2914             TCollection_AsciiString aFieldStepName;
2915             double aFieldStepRangeMin, aFieldStepRangeMax;
2916             aShape->getFieldStepInfo( aFieldDataType,
2917                                       aFieldDimension,
2918                                       aFieldStepData,
2919                                       aFieldStepName,
2920                                       aFieldStepRangeMin,
2921                                       aFieldStepRangeMax );
2922             if( !aFieldStepData.isEmpty() && aFieldDataType != GEOM::FDT_String )
2923             {
2924               anIsDisplayColorScale = Standard_True;
2925               aColorScaleTitle = aFieldStepName;
2926               aColorScaleMin = aFieldStepRangeMin;
2927               aColorScaleMax = aFieldStepRangeMax;
2928               anIsBoolean = aFieldDataType == GEOM::FDT_Bool;
2929             }
2930           }
2931         }
2932       }
2933     }
2934   }
2935
2936   if( anIsDisplayColorScale )
2937   {
2938     Handle(Aspect_ColorScale) aColorScale = aView->ColorScale();
2939     if( !aColorScale.IsNull() )
2940     {
2941       SUIT_Session* session = SUIT_Session::session();
2942       SUIT_ResourceMgr* resMgr = session->resourceMgr();
2943
2944       Standard_Real anXPos = resMgr->doubleValue( "Geometry", "scalar_bar_x_position", 0.05 );
2945       Standard_Real anYPos = resMgr->doubleValue( "Geometry", "scalar_bar_y_position", 0.1 );
2946       Standard_Real aWidth = resMgr->doubleValue( "Geometry", "scalar_bar_width", 0.2 );
2947       Standard_Real aHeight = resMgr->doubleValue( "Geometry", "scalar_bar_height", 0.5 );
2948       Standard_Integer aTextHeight = resMgr->integerValue( "Geometry", "scalar_bar_text_height", 14 );
2949       Standard_Integer aNbIntervals = resMgr->integerValue( "Geometry", "scalar_bar_nb_intervals", 20 );
2950  
2951       aColorScale->SetXPosition( anXPos );
2952       aColorScale->SetYPosition( anYPos );
2953       aColorScale->SetWidth( aWidth );
2954       aColorScale->SetHeight( aHeight );
2955
2956       aColorScale->SetTextHeight( aTextHeight );
2957       aColorScale->SetNumberOfIntervals( anIsBoolean ? 2 : aNbIntervals );
2958
2959       aColorScale->SetTitle( aColorScaleTitle );
2960       aColorScale->SetRange( aColorScaleMin, aColorScaleMax );
2961     }
2962     if( !aView->ColorScaleIsDisplayed() )
2963       aView->ColorScaleDisplay();
2964   }
2965   else
2966   {
2967     if( aView->ColorScaleIsDisplayed() )
2968       aView->ColorScaleErase();
2969   }
2970
2971   if( theIsRedisplayFieldSteps )
2972   {
2973     _PTR(Study) aStudyDS = aStudy->studyDS();
2974     QList<SUIT_ViewManager*> vmList;
2975     myApp->viewManagers( vmList );
2976     for( QList<SUIT_ViewManager*>::Iterator vmIt = vmList.begin(); vmIt != vmList.end(); vmIt++ )
2977     {
2978       if( SUIT_ViewManager* aViewManager = *vmIt )
2979       {
2980         const ObjMap anObjects = aStudy->getObjectMap( aViewManager->getGlobalId() );
2981         for( ObjMap::ConstIterator objIt = anObjects.begin(); objIt != anObjects.end(); objIt++ )
2982         {
2983           _PTR(SObject) aSObj( aStudyDS->FindObjectID( objIt.key().toLatin1().constData() ) );
2984           if( aSObj )
2985           {
2986             CORBA::Object_var anObject = GeometryGUI::ClientSObjectToObject( aSObj );
2987             if( !CORBA::is_nil( anObject ) )
2988             {
2989               GEOM::GEOM_FieldStep_var aFieldStep = GEOM::GEOM_FieldStep::_narrow( anObject );
2990               if( !aFieldStep->_is_nil() )
2991               {
2992                 CORBA::String_var aStepEntry = aFieldStep->GetStudyEntry();
2993                 Handle(SALOME_InteractiveObject) aStepIO =
2994                   new SALOME_InteractiveObject( aStepEntry.in(), "GEOM", "TEMP_IO" );
2995                 Redisplay( aStepIO, false, false );
2996               }
2997             }
2998           }
2999         }
3000       }
3001     }
3002   }
3003   if(updateViewer)
3004     UpdateViewer();
3005 }