Salome HOME
1a69cfb938d258afc3380b5f8b98e099f09ba8dd
[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 <AIS_Drawer.hxx>
26
27 #include <BRepBuilderAPI_MakeEdge.hxx>
28 #include <BRepBuilderAPI_MakeWire.hxx>
29 #include <BRepBuilderAPI_MakeFace.hxx>
30
31 #include <gp_Pnt.hxx>
32
33 #include <Graphic3d_AspectFillArea3d.hxx>
34 #include <Graphic3d_MaterialAspect.hxx>
35
36 #include <HYDROData_Domain.h>
37 #include <HYDROData_Polyline.h>
38
39 #include <TopoDS_Wire.hxx>
40 #include <TopoDS_Face.hxx>
41
42 #include <Precision.hxx>
43
44 #include <Prs3d_ShadingAspect.hxx>
45 #include <Prs3d_LineAspect.hxx>
46 #include <Prs3d_IsoAspect.hxx>
47
48 #include <QColor>
49
50 HYDROGUI_Shape::HYDROGUI_Shape( const Handle(AIS_InteractiveContext)& theContext,
51                                 const Handle(HYDROData_Object)&       theObject )
52 : myContext( theContext ),
53   myObject( theObject ),
54   myIsHighlight( false ),
55   myFillingColor( Qt::transparent ),
56   myBorderColor( Qt::black ),
57   myHighlightColor( Qt::white ),
58   myIsToUpdate( false ),
59   myIsVisible( true ),
60   myDisplayMode( AIS_WireFrame )
61 {
62 }
63
64 HYDROGUI_Shape::~HYDROGUI_Shape()
65 {
66   erase();
67
68   if ( !myShape.IsNull() )
69     myShape.Nullify();
70 }
71
72 void HYDROGUI_Shape::display( const bool theIsUpdateViewer )
73 {
74   if ( myContext.IsNull() || myShape.IsNull() || !isVisible() )
75     return;
76
77   myContext->Display( myShape, theIsUpdateViewer );
78 }
79
80 void HYDROGUI_Shape::erase( const bool theIsUpdateViewer )
81 {
82   if ( myContext.IsNull() || myShape.IsNull() )
83     return;
84
85   myContext->Erase( myShape, theIsUpdateViewer );
86 }
87
88 void HYDROGUI_Shape::update( const bool theIsUpdateViewer )
89 {
90   setIsToUpdate( false );
91
92   if ( myContext.IsNull() )
93     return;
94
95   // Try to retrieve information from object
96   if ( !myObject.IsNull() )
97   {
98     if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Domain) ) )
99     {
100       Handle(HYDROData_Domain) aDomainObj =
101         Handle(HYDROData_Domain)::DownCast( myObject );
102
103       QColor aFillingColor = aDomainObj->GetFillingColor();
104       QColor aBorderColor = aDomainObj->GetBorderColor();
105       TopoDS_Face aDomainFace = aDomainObj->Face();
106
107       setFillingColor( aFillingColor, false, false );
108       setBorderColor( aBorderColor, false, false );
109       setFace( aDomainFace, false, false );
110     }
111     else if ( myObject->IsKind( STANDARD_TYPE(HYDROData_Polyline) ) )
112     {
113       Handle(HYDROData_Polyline) aPolyline =
114         Handle(HYDROData_Polyline)::DownCast( myObject );
115
116       TopoDS_Wire aPolylineWire = aPolyline->Wire();
117
118       setWire( aPolylineWire, false, false );
119     }
120   }
121
122   if ( myShape.IsNull() || !isVisible() )
123     return;
124
125   myContext->Display( myShape, theIsUpdateViewer );
126 }
127
128 void HYDROGUI_Shape::setVisible( const bool theState,
129                                  const bool theIsUpdateViewer )
130 {
131   if ( myIsVisible == theState )
132     return;
133
134   myIsVisible = theState;
135
136   if ( myShape.IsNull() )
137     return;
138
139   if ( myIsVisible )
140     myContext->Display( myShape, theIsUpdateViewer );
141   else
142     myContext->Erase( myShape, theIsUpdateViewer );
143 }
144
145 void HYDROGUI_Shape::highlight( bool theIsHighlight )
146 {
147   if ( myIsHighlight == theIsHighlight )
148     return;
149
150   myIsHighlight = theIsHighlight;
151
152   if ( myContext.IsNull() || myShape.IsNull() )
153     return;
154
155   colorShapeBorder( getActiveColor() );
156   myContext->Display( myShape );
157 }
158
159 bool HYDROGUI_Shape::isHighlighted() const
160 {
161   return myIsHighlight;
162 }
163
164 void HYDROGUI_Shape::setWire( const TopoDS_Wire& theWire,
165                               const bool         theToDisplay,
166                               const bool         theIsUpdateViewer )
167 {
168   myTopoShape = theWire;
169   myDisplayMode = AIS_WireFrame;
170
171   buildShape();
172   updateShape( theToDisplay, theIsUpdateViewer );
173 }
174
175 void HYDROGUI_Shape::setFace( const TopoDS_Wire& theWire,
176                               const bool         theToDisplay,
177                               const bool         theIsUpdateViewer )
178 {
179   BRepBuilderAPI_MakeFace aFaceBuilder( theWire, Standard_True );
180   aFaceBuilder.Build();
181   if( aFaceBuilder.IsDone() )
182   {
183     TopoDS_Face aFace = aFaceBuilder.Face();
184     setFace( aFace, theToDisplay, theIsUpdateViewer );
185   }
186 }
187
188 void HYDROGUI_Shape::setFace( const TopoDS_Face& theFace,
189                               const bool         theToDisplay,
190                               const bool         theIsUpdateViewer )
191 {
192   myTopoShape = theFace;
193   myDisplayMode = AIS_Shaded;
194
195   buildShape();
196   updateShape( theToDisplay, theIsUpdateViewer );
197 }
198
199 void HYDROGUI_Shape::setFillingColor( const QColor& theColor,
200                                       const bool    theToDisplay,
201                                       const bool    theIsUpdateViewer )
202 {
203   myFillingColor = theColor;
204   updateShape( theToDisplay, theIsUpdateViewer );
205 }
206
207 QColor HYDROGUI_Shape::getFillingColor() const
208 {
209   return myFillingColor;
210 }
211
212 void HYDROGUI_Shape::setBorderColor( const QColor& theColor,
213                                      const bool    theToDisplay,
214                                      const bool    theIsUpdateViewer )
215 {
216   myBorderColor = theColor;
217   updateShape( theToDisplay, theIsUpdateViewer );
218 }
219
220 QColor HYDROGUI_Shape::getBorderColor() const
221 {
222   return myBorderColor;
223 }
224
225 void HYDROGUI_Shape::setHighlightColor( const QColor& theColor )
226 {
227   myHighlightColor = theColor;
228 }
229
230 QColor HYDROGUI_Shape::getHighlightColor() const
231 {
232   return myHighlightColor;
233 }
234
235 void HYDROGUI_Shape::buildShape()
236 {
237   // Erase previously created shape
238   erase();
239
240   if ( myTopoShape.IsNull() )
241     return;
242
243   myShape = new AIS_Shape( myTopoShape );
244
245   if ( !myObject.IsNull() )
246     myShape->SetOwner( myObject );
247
248   myShape->SetTransparency( 0 );
249   myShape->SetDisplayMode( (AIS_DisplayMode)myDisplayMode );
250
251     // Init default params for shape
252   const Handle(AIS_Drawer)& anAttributes = myShape->Attributes();
253   if ( !anAttributes.IsNull() )
254   {
255     if ( myDisplayMode == AIS_Shaded )
256     {
257       Handle(Prs3d_IsoAspect) anIsoAspect = anAttributes->UIsoAspect();
258       if ( !anIsoAspect.IsNull() )
259         anIsoAspect->SetNumber( 0 );
260       
261       anIsoAspect = anAttributes->VIsoAspect();
262       if ( !anIsoAspect.IsNull() )
263         anIsoAspect->SetNumber( 0 );
264
265       Handle(Prs3d_ShadingAspect) aShadingAspect = anAttributes->ShadingAspect();
266       if ( !aShadingAspect.IsNull() )
267       {
268         Graphic3d_MaterialAspect aMatAspect;
269         aMatAspect.SetAmbient( 1 );
270         aMatAspect.SetDiffuse( 0 );
271
272         aShadingAspect->Aspect()->SetFrontMaterial( aMatAspect );
273         aShadingAspect->Aspect()->SetBackMaterial( aMatAspect );
274       }
275     }
276     else if ( myDisplayMode == AIS_WireFrame )
277     {
278       anAttributes->SetWireDraw( true );
279     }
280   }
281 }
282
283 void HYDROGUI_Shape::updateShape( const bool theToDisplay,
284                                   const bool theIsUpdateViewer )
285 {
286   if ( myShape.IsNull() )
287     return;
288
289   const Handle(AIS_Drawer)& anAttributes = myShape->Attributes();
290   if ( !anAttributes.IsNull() )
291   {
292     if ( myDisplayMode == AIS_Shaded )
293     {
294       // Coloring face filling
295       Handle(Prs3d_ShadingAspect) aShadingAspect = anAttributes->ShadingAspect();
296       if ( !aShadingAspect.IsNull() )
297       {
298         Quantity_Color aFillingColor( getQuantityColorVal( myFillingColor.red() ), 
299                                       getQuantityColorVal( myFillingColor.green() ),
300                                       getQuantityColorVal( myFillingColor.blue() ),
301                                       Quantity_TOC_RGB );
302
303         aShadingAspect->SetColor( aFillingColor );
304         aShadingAspect->SetTransparency( 1 - getQuantityColorVal( myFillingColor.alpha() ) );
305       }
306     }
307     else if ( myDisplayMode == AIS_WireFrame )
308     {
309     }
310
311     // Coloring borders
312     colorShapeBorder( getActiveColor() );
313   }
314
315   if ( !theToDisplay || !isVisible() || myContext.IsNull() )
316     return;
317   
318   myContext->Display( myShape, theIsUpdateViewer );
319 }
320
321 QColor HYDROGUI_Shape::getActiveColor() const
322 {
323   return isHighlighted() ? myHighlightColor : myBorderColor;
324 }
325
326 double HYDROGUI_Shape::getQuantityColorVal( const int theColorVal )
327 {
328   return theColorVal == 0 ? 0 : ( (double)theColorVal / 255 );
329 }
330
331 void HYDROGUI_Shape::colorShapeBorder( const QColor& theColor )
332 {
333   if ( myShape.IsNull() )
334     return;
335
336   const Handle(AIS_Drawer)& anAttributes = myShape->Attributes();
337   if ( anAttributes.IsNull() )
338     return;
339
340   Quantity_Color aBorderColor( getQuantityColorVal( theColor.red() ), 
341                                getQuantityColorVal( theColor.green() ),
342                                getQuantityColorVal( theColor.blue() ),
343                                Quantity_TOC_RGB );
344   if ( myDisplayMode == AIS_Shaded )
345   {
346     if ( theColor.alpha() == 0 )
347     {
348       anAttributes->SetFaceBoundaryDraw( false );
349     }
350     else
351     {
352       anAttributes->SetFaceBoundaryDraw( true );
353
354       Handle(Prs3d_LineAspect) aBoundaryAspect = anAttributes->FaceBoundaryAspect();
355       if ( !aBoundaryAspect.IsNull() )
356         aBoundaryAspect->SetColor( aBorderColor );
357     }
358   }
359   else if ( myDisplayMode == AIS_WireFrame )
360   {
361     myShape->SetColor( aBorderColor );
362   }
363 }
364
365