Salome HOME
Refs #156 - cross-dependence of images - check and error or filter
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Shape.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
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 #include "HYDROGUI_Shape.h"
24
25 #include "HYDROGUI_DataObject.h"
26 #include "HYDROGUI_Tool.h"
27
28 #include <AIS_Drawer.hxx>
29 #include <AIS_TexturedShape.hxx>
30
31 #include <BRepBuilderAPI_MakeEdge.hxx>
32 #include <BRepBuilderAPI_MakeWire.hxx>
33 #include <BRepBuilderAPI_MakeFace.hxx>
34
35 #include <gp_Pnt.hxx>
36
37 #include <Graphic3d_AspectFillArea3d.hxx>
38 #include <Graphic3d_MaterialAspect.hxx>
39
40 #include <HYDROData_Channel.h>
41 #include <HYDROData_Document.h>
42 #include <HYDROData_DummyObject3D.h>
43 #include <HYDROData_Image.h>
44 #include <HYDROData_ImmersibleZone.h>
45 #include <HYDROData_Obstacle.h>
46 #include <HYDROData_PolylineXY.h>
47 #include <HYDROData_Polyline3D.h>
48 #include <HYDROData_Profile.h>
49 #include <HYDROData_Region.h>
50 #include <HYDROData_ShapesGroup.h>
51 #include <HYDROData_Stream.h>
52 #include <HYDROData_Zone.h>
53
54 #include <TopoDS.hxx>
55 #include <TopoDS_Wire.hxx>
56 #include <TopoDS_Face.hxx>
57
58 #include <TopExp_Explorer.hxx>
59
60 #include <BRep_Builder.hxx>
61
62 #include <Precision.hxx>
63
64 #include <Prs3d_ShadingAspect.hxx>
65 #include <Prs3d_LineAspect.hxx>
66 #include <Prs3d_IsoAspect.hxx>
67
68 #include <SUIT_MessageBox.h>
69
70 #include <QColor>
71 #include <QFile>
72
73 HYDROGUI_Shape::HYDROGUI_Shape( const Handle(AIS_InteractiveContext)& theContext,
74                                 const Handle(HYDROData_Entity)&       theObject )
75 : myContext( theContext ),
76   myObject( theObject ),
77   myIsHighlight( false ),
78   myFillingColor( Qt::transparent ),
79   myBorderColor( Qt::black ),
80   myHighlightColor( Qt::white ),
81   myIsToUpdate( false ),
82   myIsVisible( true ),
83   myDisplayMode( AIS_WireFrame )
84 {
85 }
86
87 HYDROGUI_Shape::~HYDROGUI_Shape()
88 {
89   erase( false );
90
91   if ( !myShape.IsNull() )
92     myShape.Nullify();
93
94   removeTextureFile();
95 }
96
97 void HYDROGUI_Shape::display( const bool theIsUpdateViewer )
98 {
99   if ( myContext.IsNull() || myShape.IsNull() || !isVisible() )
100     return;
101
102   myContext->Display( myShape, theIsUpdateViewer );
103 }
104
105 void HYDROGUI_Shape::erase( const bool theIsUpdateViewer )
106 {
107   if ( myContext.IsNull() || myShape.IsNull() )
108     return;
109
110   myContext->Erase( myShape, theIsUpdateViewer );
111 }
112
113 void HYDROGUI_Shape::update( const bool theIsUpdateViewer )
114 {
115   setIsToUpdate( false );
116
117   if ( myContext.IsNull() )
118     return;
119
120   bool isDeactivateSelection = false;
121   // Try to retrieve information from object
122   if ( !myObject.IsNull() )
123   {
124     Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myObject->Label() );
125   
126     if ( myObject->IsKind( STANDARD_TYPE(HYDROData_ImmersibleZone) ) )
127     {
128       Handle(HYDROData_ImmersibleZone) aZoneObj =
129         Handle(HYDROData_ImmersibleZone)::DownCast( myObject );
130
131       TopoDS_Shape aZoneShape = aZoneObj->GetTopShape();
132       if ( !aZoneShape.IsNull() ) {
133         if ( aZoneShape.ShapeType() == TopAbs_FACE ) {
134           TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
135           setFace( aZoneFace, false, false );
136         } else {
137           myTopoShape = aZoneShape;
138           myDisplayMode = myTextureFileName.isEmpty() ? AIS_Shaded : AIS_Shaded+2;
139
140           buildShape();
141           updateShape( false, false );
142         }
143       }
144
145       QColor aFillingColor = aZoneObj->GetFillingColor();
146       QColor aBorderColor = aZoneObj->GetBorderColor();
147
148       setFillingColor( aFillingColor, false, false );
149       setBorderColor( aBorderColor, false, false );
150     }
151     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_PolylineXY) ) )
152     {
153       Handle(HYDROData_PolylineXY) aPolyline =
154         Handle(HYDROData_PolylineXY)::DownCast( myObject );
155
156       TopoDS_Shape aPolylineShape = aPolyline->GetShape();
157
158       if ( !aPolylineShape.IsNull() ) {
159         if ( aPolylineShape.ShapeType() == TopAbs_WIRE ) {
160           TopoDS_Wire aPolylineWire = TopoDS::Wire( aPolylineShape );
161           setWire( aPolylineWire, false, false );  
162         } else {
163           myTopoShape = aPolylineShape;
164           myDisplayMode = AIS_WireFrame;
165
166           buildShape();
167           updateShape( false, false );
168         }
169       }
170
171       QColor aWireColor = aPolyline->GetWireColor();
172       setBorderColor( aWireColor, false, false );
173     }
174     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Polyline3D) ) )
175     {
176       Handle(HYDROData_Polyline3D) aPolyline =
177         Handle(HYDROData_Polyline3D)::DownCast( myObject );
178
179       TopoDS_Shape aPolylineShape = aPolyline->GetShape3D();
180
181       if ( !aPolylineShape.IsNull() ) {
182         if ( aPolylineShape.ShapeType() == TopAbs_WIRE ) {
183           TopoDS_Wire aPolylineWire = TopoDS::Wire( aPolylineShape );
184           setWire( aPolylineWire, false, false );  
185         } else {
186           myTopoShape = aPolylineShape;
187           myDisplayMode = AIS_WireFrame;
188
189           buildShape();
190           updateShape( false, false );
191         }
192       }
193
194       QColor aWireColor = aPolyline->GetBorderColor();
195       setBorderColor( aWireColor, false, false );
196     }
197     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Zone) ) )
198     {
199       Handle(HYDROData_Zone) aZone =
200         Handle(HYDROData_Zone)::DownCast( myObject );
201
202       TopoDS_Face aZoneFace = TopoDS::Face( aZone->GetShape() );
203
204       setFace( aZoneFace, false, false );
205       if (aZone->IsMergingNeed() && aZone->GetMergeType() == HYDROData_Zone::Merge_UNKNOWN )
206       {
207         // Red color for a zone with bathymetry conflict
208         setFillingColor( Qt::red );
209       }
210       else
211       {
212         // Generate the filling color for zone
213         QStringList aGeomObjectsNames;
214
215         HYDROData_SequenceOfObjects aRefObjects = aZone->GetGeometryObjects();
216         HYDROData_SequenceOfObjects::Iterator anIter( aRefObjects );
217         for ( ; anIter.More(); anIter.Next() )
218         {
219           Handle(HYDROData_Object) aRefbject = 
220             Handle(HYDROData_Object)::DownCast( anIter.Value() );
221           if ( aRefbject.IsNull() )
222             continue;
223
224           QString aRefObjectName = aRefbject->GetName();
225           if ( aRefObjectName.isEmpty() )
226             continue;
227
228           aGeomObjectsNames.append( aRefObjectName );
229         }
230
231         setFillingColor( HYDROGUI_Tool::GenerateFillingColor( aDocument, aGeomObjectsNames ) );
232       }
233     }
234     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Image) ) )
235     {
236       Handle(HYDROData_Image) anImageObj =
237         Handle(HYDROData_Image)::DownCast( myObject );
238
239       removeTextureFile();
240
241       QString aTextureFileName = generateTextureFileName( anImageObj );
242
243       QImage anImage = anImageObj->Image();
244       QString aFilePath = anImageObj->GetFilePath();
245       QTransform aTrsf = anImageObj->Trsf();
246
247       int aWidth = anImage.width();
248       int aHeight = anImage.height();
249
250       QTransform anInversion = QTransform::fromScale( -1, -1 );
251       anImage = anImage.transformed( anInversion * aTrsf, Qt::SmoothTransformation );
252
253       // Workaround: Scale the texture image to the nearest width multiple 4 due to the CASCADE bug 23813
254       int aTrsfWidth = anImage.width();
255       int aDelta = aTrsfWidth % 4;
256       if ( aDelta > 0 )
257       {
258         aTrsfWidth += ( 4 - aDelta );
259       }
260       anImage = anImage.scaledToWidth( aTrsfWidth );
261
262       // temporary optimization, to reduce the saved image size (and the texture quality)
263       QImage anImageToSave = anImage; //RKV:reduceTexture( anImage, 500 );
264
265       bool isSaved = anImageToSave.save( aTextureFileName );
266       if ( !isSaved ) {
267         QString aTitle = QObject::tr( "FILE_ERROR" );
268         QString aMessage = QObject::tr( "FILE_CAN_NOT_BE_CREATED" ).arg( aTextureFileName );
269         SUIT_MessageBox::warning( 0, aTitle, aMessage );
270       }
271
272       QPointF aPoint1( 0, 0 );            // 1: top left
273       QPointF aPoint2( aWidth, 0 );       // 2: top right
274       QPointF aPoint3( aWidth, aHeight ); // 3: bottom right
275       QPointF aPoint4( 0, aHeight );      // 4: bottom left
276
277       aPoint1 = aTrsf.map( aPoint1 );
278       aPoint2 = aTrsf.map( aPoint2 );
279       aPoint3 = aTrsf.map( aPoint3 );
280       aPoint4 = aTrsf.map( aPoint4 );
281
282       QPolygonF aPolygon = QPolygonF() << aPoint1 << aPoint2 << aPoint3 << aPoint4;
283       QRectF aRect = aPolygon.boundingRect();
284
285       gp_Pnt aPnt1( aRect.topLeft().x(), aRect.topLeft().y(), 0 );
286       gp_Pnt aPnt2( aRect.topRight().x(), aRect.topRight().y(), 0 );
287       gp_Pnt aPnt3( aRect.bottomRight().x(), aRect.bottomRight().y(), 0 );
288       gp_Pnt aPnt4( aRect.bottomLeft().x(), aRect.bottomLeft().y(), 0 );
289
290       TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge();
291       TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge( aPnt2, aPnt3 ).Edge();
292       TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge( aPnt3, aPnt4 ).Edge();
293       TopoDS_Edge anEdge4 = BRepBuilderAPI_MakeEdge( aPnt4, aPnt1 ).Edge();
294
295       TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge1, anEdge2, anEdge3, anEdge4 ).Wire();
296       aWire.Closed( true );
297
298       setTextureFileName( aTextureFileName, false, false );
299       setFace( aWire, false, false );
300       isDeactivateSelection = true;
301     }
302     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Profile) ) )
303     {
304       Handle(HYDROData_Profile) aProfile =
305         Handle(HYDROData_Profile)::DownCast( myObject );
306
307       TopoDS_Wire aProfileWire;
308
309       if ( aProfile->IsValid() ) {
310         TopoDS_Shape aProfileShape = aProfile->GetShape3D();
311
312         if ( !aProfileShape.IsNull() && 
313              aProfileShape.ShapeType() == TopAbs_WIRE ) {
314           aProfileWire = TopoDS::Wire( aProfileShape );
315         }
316       }
317
318       setWire( aProfileWire, false, false );  
319
320       QColor aWireColor = aProfile->GetBorderColor();
321       setBorderColor( aWireColor, false, false );
322     }
323     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Stream) ) ||
324               myObject->IsKind( STANDARD_TYPE(HYDROData_Channel) ) ||
325               myObject->IsKind( STANDARD_TYPE(HYDROData_Obstacle) ) )
326     {
327       Handle(HYDROData_Object) aGeomObject =
328         Handle(HYDROData_Object)::DownCast( myObject );
329
330       TopoDS_Shape anObjShape = aGeomObject->GetTopShape();
331
332       setShape( anObjShape, false, false );
333
334       QColor aFillingColor = aGeomObject->GetFillingColor();
335       QColor aBorderColor = aGeomObject->GetBorderColor();
336
337       setFillingColor( aFillingColor, false, false );
338       setBorderColor( aBorderColor, false, false );
339     }
340     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_DummyObject3D) ) )
341     {
342       Handle(HYDROData_DummyObject3D) anObject3D =
343         Handle(HYDROData_DummyObject3D)::DownCast( myObject );
344       TopoDS_Shape aShape3D = anObject3D->GetShape();
345
346       setShape( aShape3D, false, false );
347
348       QColor aFillingColor = anObject3D->GetFillingColor();
349       QColor aBorderColor = anObject3D->GetBorderColor();
350
351       setFillingColor( aFillingColor, false, false );
352       setBorderColor( aBorderColor, false, false );
353     }
354     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_ShapesGroup) ) )
355     {
356       Handle(HYDROData_ShapesGroup) aShapesGroup =
357         Handle(HYDROData_ShapesGroup)::DownCast( myObject );
358
359       TopTools_SequenceOfShape aShapes;
360       aShapesGroup->GetShapes( aShapes );
361
362       BRepBuilderAPI_MakeWire aMakeWire;
363
364       for ( int i = 1, n = aShapes.Length(); i <= n; ++i )
365       {
366         TopoDS_Edge anEdge = TopoDS::Edge( aShapes.Value( i ) );
367         aMakeWire.Add( anEdge );
368       }
369
370       aMakeWire.Build();
371       TopoDS_Wire aResWire = aMakeWire.Wire();
372
373       setWire( aResWire, false, false );  
374       setBorderColor( Qt::red, false, false );
375     }
376   }
377  
378   if ( myShape.IsNull() || !isVisible() )
379     return;
380
381   myContext->Display( myShape, theIsUpdateViewer );
382   if (isDeactivateSelection)
383     myContext->Deactivate(myShape);
384 }
385
386 void HYDROGUI_Shape::setVisible( const bool theState,
387                                  const bool theIsUpdateViewer )
388 {
389   if ( myIsVisible == theState )
390     return;
391
392   myIsVisible = theState;
393
394   if ( myShape.IsNull() )
395     return;
396
397   if ( myIsVisible )
398     myContext->Display( myShape, theIsUpdateViewer );
399   else
400     myContext->Erase( myShape, theIsUpdateViewer );
401 }
402
403 void HYDROGUI_Shape::highlight( bool theIsHighlight, bool isUpdateViewer )
404 {
405   if ( myIsHighlight == theIsHighlight )
406     return;
407
408   myIsHighlight = theIsHighlight;
409
410   if ( myContext.IsNull() || myShape.IsNull() )
411     return;
412
413   colorShapeBorder( getActiveColor() );
414   myContext->Display( myShape, isUpdateViewer );
415 }
416
417 bool HYDROGUI_Shape::isHighlighted() const
418 {
419   return myIsHighlight;
420 }
421
422 void HYDROGUI_Shape::setWire( const TopoDS_Wire& theWire,
423                               const bool         theToDisplay,
424                               const bool         theIsUpdateViewer )
425 {
426   myTopoShape = theWire;
427   myDisplayMode = AIS_WireFrame;
428
429   buildShape();
430   updateShape( theToDisplay, theIsUpdateViewer );
431 }
432
433 void HYDROGUI_Shape::setFaces( const TopoDS_Compound& theWires,
434                                const bool             theToDisplay,
435                                const bool             theIsUpdateViewer )
436 {
437   TopExp_Explorer anExp( theWires, TopAbs_WIRE );
438   TopoDS_Compound aCompound;
439   BRep_Builder aBuilder;
440     aBuilder.MakeCompound( aCompound );
441
442   for ( ; anExp.More(); anExp.Next() ) {
443     TopoDS_Wire aWire = TopoDS::Wire( anExp.Current() );
444     if ( aWire.IsNull() ) {
445       continue;
446     }
447
448     BRepBuilderAPI_MakeFace aMakeFace( aWire, Standard_True );
449     aMakeFace.Build();
450     if( aMakeFace.IsDone() ) {
451       aBuilder.Add( aCompound, aMakeFace.Face() );
452     }
453   }
454
455   myTopoShape = aCompound;
456   myDisplayMode = AIS_Shaded;
457
458   buildShape();
459   updateShape( theToDisplay, theIsUpdateViewer );
460 }
461
462 void HYDROGUI_Shape::setFace( const TopoDS_Wire& theWire,
463                               const bool         theToDisplay,
464                               const bool         theIsUpdateViewer )
465 {
466   BRepBuilderAPI_MakeFace aFaceBuilder( theWire, Standard_True );
467   aFaceBuilder.Build();
468   if( aFaceBuilder.IsDone() )
469   {
470     TopoDS_Face aFace = aFaceBuilder.Face();
471     setFace( aFace, theToDisplay, theIsUpdateViewer );
472   }
473 }
474
475 void HYDROGUI_Shape::setFace( const TopoDS_Face& theFace,
476                               const bool         theToDisplay,
477                               const bool         theIsUpdateViewer )
478 {
479   myTopoShape = theFace;
480   myDisplayMode = myTextureFileName.isEmpty() ? AIS_Shaded : AIS_Shaded+2;
481   //Note: AIS_Shaded+2 is the same as AIS_ExactHLR
482   //TODO: it would be more suitable to use TexturedShape mode from GEOM_AISShape
483
484   buildShape();
485   updateShape( theToDisplay, theIsUpdateViewer );
486 }
487
488 void HYDROGUI_Shape::setShape( const TopoDS_Shape& theShape,
489                                const bool          theToDisplay,
490                                const bool          theIsUpdateViewer )
491 {
492   myTopoShape = theShape;
493   myDisplayMode = AIS_Shaded;
494
495   buildShape();
496   updateShape( theToDisplay, theIsUpdateViewer );
497 }
498
499 void HYDROGUI_Shape::setFillingColor( const QColor& theColor,
500                                       const bool    theToDisplay,
501                                       const bool    theIsUpdateViewer )
502 {
503   myFillingColor = theColor;
504   updateShape( theToDisplay, theIsUpdateViewer );
505 }
506
507 QColor HYDROGUI_Shape::getFillingColor() const
508 {
509   return myFillingColor;
510 }
511
512 void HYDROGUI_Shape::setBorderColor( const QColor& theColor,
513                                      const bool    theToDisplay,
514                                      const bool    theIsUpdateViewer )
515 {
516   myBorderColor = theColor;
517   updateShape( theToDisplay, theIsUpdateViewer );
518 }
519
520 QColor HYDROGUI_Shape::getBorderColor() const
521 {
522   return myBorderColor;
523 }
524
525 void HYDROGUI_Shape::setHighlightColor( const QColor& theColor )
526 {
527   myHighlightColor = theColor;
528 }
529
530 QColor HYDROGUI_Shape::getHighlightColor() const
531 {
532   return myHighlightColor;
533 }
534
535 void HYDROGUI_Shape::setTextureFileName( const QString& theFileName,
536                                          const bool     theToDisplay,
537                                          const bool     theIsUpdateViewer )
538 {
539   myTextureFileName = theFileName;
540   updateShape( theToDisplay, theIsUpdateViewer );
541 }
542
543 QString HYDROGUI_Shape::getTextureFileName() const
544 {
545   return myTextureFileName;
546 }
547
548 void HYDROGUI_Shape::buildShape()
549 {
550   // Erase previously created shape
551   erase();
552
553   if ( myTopoShape.IsNull() ) {
554     myShape.Nullify();
555     return;
556   }
557
558   QString aTextureFileName = getTextureFileName();
559   bool anIsTexture = !aTextureFileName.isEmpty();
560
561   if ( anIsTexture )
562   {
563     myShape = new AIS_TexturedShape( myTopoShape );
564   }
565   else
566   {
567     myShape = new AIS_Shape( myTopoShape );
568   }
569
570   if ( !myObject.IsNull() )
571     myShape->SetOwner( myObject );
572
573   myShape->SetTransparency( 0 );
574   myShape->SetDisplayMode( (AIS_DisplayMode)myDisplayMode );
575
576   if( anIsTexture )
577   {
578     Handle(AIS_TexturedShape) aTexturedShape = 
579       Handle(AIS_TexturedShape)::DownCast( myShape );
580
581     aTexturedShape->SetTextureFileName( HYDROGUI_Tool::ToAsciiString( aTextureFileName ) );
582     aTexturedShape->SetTextureMapOn();
583     // Just use the texture image as is
584     aTexturedShape->DisableTextureModulate();
585     aTexturedShape->SetTextureRepeat( false ); // don't repeat the texture image on the face
586   }
587
588     // Init default params for shape
589   const Handle(AIS_Drawer)& anAttributes = myShape->Attributes();
590   if ( !anAttributes.IsNull() )
591   {
592     Handle(Prs3d_IsoAspect) anIsoAspect = anAttributes->UIsoAspect();
593     if ( !anIsoAspect.IsNull() ) {
594       anIsoAspect->SetNumber( 0 );
595       anAttributes->SetUIsoAspect( anIsoAspect );
596     }
597       
598     anIsoAspect = anAttributes->VIsoAspect();
599     if ( !anIsoAspect.IsNull() ) {
600       anIsoAspect->SetNumber( 0 );
601       anAttributes->SetVIsoAspect( anIsoAspect );
602     }
603
604     if ( myDisplayMode == AIS_Shaded )
605     {
606       Handle(Prs3d_ShadingAspect) aShadingAspect = anAttributes->ShadingAspect();
607       if ( !aShadingAspect.IsNull() )
608       {
609         Graphic3d_MaterialAspect aMatAspect;
610         aMatAspect.SetAmbient( 1 );
611         aMatAspect.SetDiffuse( 0 );
612
613         aShadingAspect->Aspect()->SetFrontMaterial( aMatAspect );
614         aShadingAspect->Aspect()->SetBackMaterial( aMatAspect );
615       }
616     }
617     else if ( myDisplayMode == AIS_WireFrame )
618     {
619       anAttributes->SetWireDraw( true );
620     }
621   }
622 }
623
624 void HYDROGUI_Shape::updateShape( const bool theToDisplay,
625                                   const bool theIsUpdateViewer )
626 {
627   if ( myShape.IsNull() )
628     return;
629
630   const Handle(AIS_Drawer)& anAttributes = myShape->Attributes();
631   if ( !anAttributes.IsNull() )
632   {
633     if ( myDisplayMode == AIS_Shaded )
634     {
635       // Coloring face filling
636       Handle(Prs3d_ShadingAspect) aShadingAspect = anAttributes->ShadingAspect();
637       if ( !aShadingAspect.IsNull() )
638       {
639         Quantity_Color aFillingColor( getQuantityColorVal( myFillingColor.red() ), 
640                                       getQuantityColorVal( myFillingColor.green() ),
641                                       getQuantityColorVal( myFillingColor.blue() ),
642                                       Quantity_TOC_RGB );
643
644         aShadingAspect->SetColor( aFillingColor );
645         aShadingAspect->SetTransparency( 1 - getQuantityColorVal( myFillingColor.alpha() ) );
646       }
647     }
648     else if ( myDisplayMode == AIS_WireFrame )
649     {
650     }
651
652     // Coloring borders
653     colorShapeBorder( getActiveColor() );
654   }
655
656   if ( !theToDisplay || !isVisible() || myContext.IsNull() )
657     return;
658   
659   myContext->Display( myShape, theIsUpdateViewer );
660 }
661
662 QColor HYDROGUI_Shape::getActiveColor() const
663 {
664   return isHighlighted() ? myHighlightColor : myBorderColor;
665 }
666
667 double HYDROGUI_Shape::getQuantityColorVal( const int theColorVal )
668 {
669   return theColorVal == 0 ? 0 : ( (double)theColorVal / 255 );
670 }
671
672 void HYDROGUI_Shape::colorShapeBorder( const QColor& theColor )
673 {
674   if ( myShape.IsNull() )
675     return;
676
677   const Handle(AIS_Drawer)& anAttributes = myShape->Attributes();
678   if ( anAttributes.IsNull() )
679     return;
680
681   Quantity_Color aBorderColor( getQuantityColorVal( theColor.red() ), 
682                                getQuantityColorVal( theColor.green() ),
683                                getQuantityColorVal( theColor.blue() ),
684                                Quantity_TOC_RGB );
685   if ( myDisplayMode == AIS_Shaded )
686   {
687     if ( theColor.alpha() == 0 )
688     {
689       anAttributes->SetFaceBoundaryDraw( false );
690     }
691     else
692     {
693       anAttributes->SetFaceBoundaryDraw( true );
694
695       Handle(Prs3d_LineAspect) aBoundaryAspect = anAttributes->FaceBoundaryAspect();
696       if ( !aBoundaryAspect.IsNull() )
697       {
698         aBoundaryAspect->SetColor( aBorderColor );
699         anAttributes->SetFaceBoundaryAspect( aBoundaryAspect );
700       }
701     }
702   }
703   else if ( myDisplayMode == AIS_WireFrame )
704   {
705     myShape->SetColor( aBorderColor );
706   }
707 }
708
709 QString HYDROGUI_Shape::generateTextureFileName( const Handle(HYDROData_Entity)& theImageObj )
710 {
711   QString aResult;
712   if( !theImageObj.IsNull() )
713   {
714     QString aTempDir = HYDROGUI_Tool::GetTempDir( true );
715
716     int aStudyId = HYDROGUI_Tool::GetActiveStudyId();
717     QString aPrefix = QString( "image_%1" ).arg( aStudyId );
718
719     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( theImageObj, false );
720     anEntry.replace( ':', '_' );
721
722     QString anExtension = "bmp";
723
724     aResult = QString( "%1/%2_%3.%4" ).arg( aTempDir, aPrefix, anEntry, anExtension );
725   }
726   return aResult;
727 }
728
729 void HYDROGUI_Shape::removeTextureFile() const
730 {
731   QFile aFile( getTextureFileName() );
732   if( aFile.exists() )
733     aFile.remove();
734 }
735
736 QImage HYDROGUI_Shape::reduceTexture( const QImage& theImage, const int theSizeLimit )
737 {
738   double aSizeLimit = (double)theSizeLimit;
739   double aWidth = (double)theImage.width();
740   double aHeight = (double)theImage.height();
741   if( aWidth > aSizeLimit || aHeight > aSizeLimit )
742   {
743     if( aWidth > aHeight )
744     {
745       aHeight /= ( aWidth / aSizeLimit );
746       aWidth = aSizeLimit;
747     }
748     else
749     {
750       aWidth /= ( aHeight / aSizeLimit );
751       aHeight = aSizeLimit;
752     }
753   }
754   return theImage.scaled( aWidth, aHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation );
755 }