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