8de4fcf5b47e1da8cc16421c3fbb47ecbe6a9aba
[occt.git] / src / MeshVS / MeshVS_NodalColorPrsBuilder.cxx
1 // Created on: 2003-11-12
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2003-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #define _POLYGONES_
22 // if define _POLYGONES_ ColorPrsBuilder use ArrayOfPolygons for drawing faces
23
24 #include <MeshVS_NodalColorPrsBuilder.ixx>
25
26 #include <Graphic3d_AspectFillArea3d.hxx>
27 #include <Graphic3d_AspectLine3d.hxx>
28 #include <Graphic3d_ArrayOfPolygons.hxx>
29 #include <Graphic3d_ArrayOfPolylines.hxx>
30 #include <Graphic3d_Vertex.hxx>
31 #include <Graphic3d_Group.hxx>
32 #include <Graphic3d_Array1OfVertex.hxx>
33
34 #include <Prs3d_ShadingAspect.hxx>
35 #include <Prs3d_Root.hxx>
36 #include <Prs3d_LineAspect.hxx>
37
38 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
39 #include <TColStd_ListIteratorOfListOfInteger.hxx>
40 #include <TColStd_Array1OfReal.hxx>
41 #include <TColStd_HArray1OfReal.hxx>
42 #include <TColStd_Array1OfInteger.hxx>
43 #include <TColStd_SequenceOfInteger.hxx>
44 #include <TColStd_HPackedMapOfInteger.hxx>
45
46 #include <MeshVS_DisplayModeFlags.hxx>
47 #include <MeshVS_DrawerAttribute.hxx>
48 #include <MeshVS_DataSource.hxx>
49 #include <MeshVS_Drawer.hxx>
50 #include <MeshVS_Mesh.hxx>
51 #include <MeshVS_MeshPrsBuilder.hxx>
52 #include <MeshVS_HArray1OfSequenceOfInteger.hxx>
53 #include <MeshVS_Buffer.hxx>
54
55 #include <gp_Pnt.hxx>
56 #include <Image_PixMap.hxx>
57 #include <Graphic3d_Texture2D.hxx>
58 #include <Graphic3d_TypeOfTextureMode.hxx>
59 #include <Standard_DefineHandle.hxx>
60 #include <PrsMgr_PresentationManager3d.hxx>
61 #include <Graphic3d_Array1OfVertexNT.hxx>
62 #include <AIS_Drawer.hxx>
63 #include <Quantity_Array1OfColor.hxx>
64 #include <Aspect_SequenceOfColor.hxx>
65
66 /*
67   Class       : MeshVS_ImageTexture2D
68   Description : Texture for nodal presentation
69 */
70 class MeshVS_ImageTexture2D : public Graphic3d_Texture2D
71 {
72 public:
73   MeshVS_ImageTexture2D (Handle(Graphic3d_StructureManager) theSM,
74                          const Image_PixMap&                theImg);
75   virtual ~MeshVS_ImageTexture2D();
76
77 public:
78   DEFINE_STANDARD_RTTI(MeshVS_ImageTexture2D)
79 };
80
81 DEFINE_STANDARD_HANDLE    (MeshVS_ImageTexture2D, Graphic3d_Texture2D)
82 IMPLEMENT_STANDARD_HANDLE (MeshVS_ImageTexture2D, Graphic3d_Texture2D)
83 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_ImageTexture2D, Graphic3d_Texture2D)
84
85 MeshVS_ImageTexture2D::MeshVS_ImageTexture2D (Handle(Graphic3d_StructureManager) theSM,
86                                               const Image_PixMap&                theImg)
87 : Graphic3d_Texture2D (theSM, "", Graphic3d_TOT_2D)
88 {
89   MyCInitTexture.doModulate = 1;
90   MyCInitTexture.doRepeat = 0;
91   MyCInitTexture.Mode = (int)Graphic3d_TOTM_MANUAL;
92   MyCInitTexture.doLinear = 1;
93   MyCInitTexture.sx = 1.0F;
94   MyCInitTexture.sy = 1.0F;
95   MyCInitTexture.tx = 0.0F;
96   MyCInitTexture.ty = 0.0F;
97   MyCInitTexture.angle = 0.0F;
98   MyCInitTexture.sparams[0] = 0.0F;
99   MyCInitTexture.sparams[1] = 0.0F;
100   MyCInitTexture.sparams[2] = 0.0F;
101   MyCInitTexture.sparams[3] = 0.0F;
102   MyCInitTexture.tparams[0] = 0.0F;
103   MyCInitTexture.tparams[1] = 0.0F;
104   MyCInitTexture.tparams[2] = 0.0F;
105   MyCInitTexture.tparams[3] = 0.0F;
106   Update();
107   LoadTexture(theImg);
108 }
109
110 MeshVS_ImageTexture2D::~MeshVS_ImageTexture2D()
111 {
112 }
113
114 //================================================================
115 // Function : getNearestPow2
116 // Purpose  : Returns the nearest power of two greater than the
117 //            argument value
118 //================================================================
119 static inline Standard_Integer getNearestPow2( Standard_Integer theValue )
120 {
121   // Precaution against overflow
122   Standard_Integer aHalfMax = IntegerLast() >> 1, aRes = 1;
123   if ( theValue > aHalfMax ) theValue = aHalfMax;
124   while ( aRes < theValue ) aRes <<= 1;
125   return aRes;
126 }
127
128 /*
129   Class       : MeshVS_NodalColorPrsBuilder
130   Description : This class provides methods to create presentation of
131                 nodes with assigned color (See hxx for more description )
132 */
133
134 //================================================================
135 // Function : Constructor MeshVS_NodalColorPrsBuilder
136 // Purpose  :
137 //================================================================
138 MeshVS_NodalColorPrsBuilder::MeshVS_NodalColorPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
139                                                            const MeshVS_DisplayModeFlags& Flags,
140                                                            const Handle (MeshVS_DataSource)& DS,
141                                                            const Standard_Integer Id,
142                                                            const MeshVS_BuilderPriority& Priority )
143 : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ),
144   myUseTexture( Standard_False ),
145   myInvalidColor( Quantity_NOC_GRAY )
146 {
147   SetExcluding ( Standard_True );
148 }
149
150 //================================================================
151 // Function : Build
152 // Purpose  :
153 //================================================================
154 void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
155                                           const TColStd_PackedMapOfInteger& IDs,
156                                           TColStd_PackedMapOfInteger& IDsToExclude,
157                                           const Standard_Boolean IsElement,
158                                           const Standard_Integer DisplayMode) const
159 {
160   Handle (MeshVS_DataSource) aSource = GetDataSource();
161   Handle (MeshVS_Drawer)     aDrawer = GetDrawer();
162   if ( aSource.IsNull() || aDrawer.IsNull() )
163     return;
164
165   Standard_Integer aMaxFaceNodes;
166   if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) || aMaxFaceNodes <= 0 )
167     return;
168
169   MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
170   TColStd_Array1OfReal aCoords ( aCoordsBuf, 1, 3 * aMaxFaceNodes );
171   Standard_Integer NbNodes;
172   MeshVS_EntityType aType;
173
174   if ( !( DisplayMode & GetFlags() ) || !IsElement )
175     return;
176
177   if ( myUseTexture && ( !myTextureCoords.Extent() || !myTextureColorMap.Length() ) ||
178        !myUseTexture && !myNodeColorMap.Extent() )
179     return;
180
181   // subtract the hidden elements and ids to exclude (to minimise allocated memory)
182   TColStd_PackedMapOfInteger anIDs;
183   anIDs.Assign( IDs );
184   Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
185   if ( !aHiddenElems.IsNull() )
186     anIDs.Subtract( aHiddenElems->Map() );
187   anIDs.Subtract( IDsToExclude );
188
189   Standard_Boolean IsReflect = Standard_False, IsMeshSmoothShading = Standard_False;
190   aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect );
191   aDrawer->GetBoolean( MeshVS_DA_SmoothShading,   IsMeshSmoothShading );
192
193   // Following parameter are used for texture presentation only
194   int nbColors = 0; // Number of colors from color map
195   int nbTextureColors = 0; // Number of colors in texture (it will be pow of 2)
196   if ( myUseTexture )
197   {
198     nbColors = myTextureColorMap.Length();
199     nbTextureColors = getNearestPow2( nbColors );
200   }
201
202   Standard_Integer aSize = anIDs.Extent();
203
204   // Calculate maximum possible number of vertices and bounds
205   Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
206   Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0;
207   TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
208   for( ; it.More(); it.Next() )
209   {
210     Standard_Integer aKey = it.Key();
211     if ( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
212       MeshVS_MeshPrsBuilder::HowManyPrimitives
213       ( aTopo, Standard_True, Standard_False, NbNodes,
214       PolygonVerticesFor3D, PolygonBoundsFor3D );
215   }
216
217   // Draw faces with nodal color
218   // OCC20644 Use "plastic" material as it is "non-physic" and so it is easier
219   // to get the required colors (see TelUpdateMaterial() function in OpenGl_attri.c)
220   Graphic3d_MaterialAspect aMaterial[ 2 ];
221   aMaterial[ 0 ] = Graphic3d_MaterialAspect( Graphic3d_NOM_PLASTIC );
222   aMaterial[ 1 ] = Graphic3d_MaterialAspect( Graphic3d_NOM_PLASTIC );
223   Standard_Integer i;
224   for ( i = 0; i < 2; i++ )
225   {
226     if ( !IsReflect )
227     {
228       aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_SPECULAR );
229       aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_AMBIENT );
230       aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_DIFFUSE );
231       aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_EMISSION );
232     }
233     else{
234       // OCC20644 Using the material with reflection properties same as in
235       // ElementalColorPrsBuilder, to get the same colors.
236       // Additionally, ambient and diffuse coefficients are used below to scale incoming colors,
237       // to simulate TelUpdateMaterial() function from OpenGl_attri.c.
238       // This is mandatory, as these "scaled" colors are then passed directly to OpenGL
239       // as ambient and diffuse colors of the current material using glColorMaterial().
240       // In ElementalColorPrsBuilder we do not need to do scale the colors, as this
241       // is done by TelUpdateMaterial().
242       // 0.5 is used to have the colors in 3D maximally similar to those in the color scale.
243       // This is possible when the sum of all coefficient is equal to 1.
244       aMaterial[i].SetAmbient( .5 );
245       aMaterial[i].SetDiffuse( .5 );
246       aMaterial[i].SetSpecular( 0. );
247       aMaterial[i].SetEmissive( 0. );
248     }
249
250  }
251
252
253   // Create array of polygons for interior presentation of faces and volumes
254   Handle(Graphic3d_ArrayOfPolygons) aCPolyArr = new Graphic3d_ArrayOfPolygons
255     ( aMaxFaceNodes * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D,
256     0, myUseTexture || IsReflect, !myUseTexture, Standard_False, myUseTexture );
257
258   // Create array of polylines for presentation of edges
259   // (used for optimization insted of SetEdgeOn method call)
260   Handle(Graphic3d_ArrayOfPolylines) aPolyL = new Graphic3d_ArrayOfPolylines
261     ( ( aMaxFaceNodes + 1 ) * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D );
262
263   gp_Pnt P, Start;
264   Standard_Real aMin = gp::Resolution() * gp::Resolution();
265   gp_Dir aDefNorm( 0., 0., 1. );
266
267   // Prepare for scaling the incoming colors
268   Standard_Real anColorRatio = aMaterial[0].Ambient();
269
270   for( it.Reset(); it.More(); it.Next() )
271   {
272     Standard_Integer aKey = it.Key();
273     if ( aSource->GetGeom  ( aKey, Standard_True, aCoords, NbNodes, aType ) )
274     {
275       MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer));
276       TColStd_Array1OfInteger aNodes(aNodesBuf, 1, NbNodes);
277       if ( !aSource->GetNodesByElement ( aKey, aNodes, NbNodes ) )
278         continue;
279
280       Quantity_Color aNColor;
281
282       Standard_Boolean isValid = Standard_True;
283       Standard_Integer i;
284       if ( myUseTexture )
285       {
286         for ( i = 1; i <= NbNodes && isValid; i++ )
287           isValid = myTextureCoords.IsBound( aNodes( i ) );
288       }
289       else
290       {
291         for ( i = 1; i <= NbNodes && isValid; i++ )
292           isValid = GetColor ( aNodes( i ), aNColor );
293       }
294
295       if ( !isValid )
296         continue;
297
298       // Preparing normal(s) to show reflections if requested
299       Handle(TColStd_HArray1OfReal) aNormals;
300       Standard_Boolean hasNormals =
301         ( IsReflect && aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals ) );
302
303       if ( aType == MeshVS_ET_Face )
304       {
305         aCPolyArr->AddBound ( NbNodes );
306         aPolyL->AddBound ( NbNodes + 1 );
307
308         for ( i = 1; i <= NbNodes; i++)
309         {
310           P = gp_Pnt( aCoords( 3 * i - 2 ), aCoords( 3 * i - 1 ), aCoords( 3 * i ) );
311           if ( myUseTexture )
312           {
313             int anId = aNodes( i );
314             double aTexCoord = myTextureCoords( anId );
315
316             // transform texture coordinate in accordance with number of colors specified
317             // by upper level and real size of Gl texture
318             // The Gl texture has border colors interpolated with the colors from the color map,
319             // thats why we need to shrink texture coordinates around the middle point to
320             // exclude areas where the map colors are interpolated with the borders color
321             double aWrapCoord = 1.0 / (2.0 * nbTextureColors) + aTexCoord * (nbColors - 1.0) / nbTextureColors;
322
323             if ( hasNormals )
324             {
325               gp_Vec aNorm(aNormals->Value( 3 * i - 2 ),
326                            aNormals->Value( 3 * i - 1 ),
327                            aNormals->Value( 3 * i     ));
328               // There are two "rows" of colors: user's invalid color at the top
329               // of texture and line of map colors at the bottom of the texture.
330               // Since the texture has borders, which are interpolated with the "rows" of colors
331               // we should specify the 0.25 offset to get the correct texture color
332               aNorm.SquareMagnitude() > aMin ?
333                 aCPolyArr->AddVertex(P, gp_Dir( aNorm ),
334                   gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ) :
335                 aCPolyArr->AddVertex(P, aDefNorm,
336                   gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
337             }
338             else
339               aCPolyArr->AddVertex( P, aDefNorm,
340                 gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
341           }
342           else
343           {
344             GetColor ( aNodes( i ), aNColor );
345
346             if ( IsReflect )
347             {
348               // Simulating TelUpdateMaterial() from OpenGl_attri.c
349               // to get the same colors in elemental and nodal color prs builders
350               aNColor.SetValues(anColorRatio * aNColor.Red(),
351                                 anColorRatio * aNColor.Green(),
352                                 anColorRatio * aNColor.Blue(),
353                                 Quantity_TOC_RGB);
354
355               if ( hasNormals )
356               {
357                 gp_Vec aNorm(aNormals->Value( 3 * i - 2 ),
358                   aNormals->Value( 3 * i - 1 ),
359                   aNormals->Value( 3 * i     ));
360                 aNorm.SquareMagnitude() > aMin ?
361                   aCPolyArr->AddVertex(P, gp_Dir( aNorm ), aNColor ) :
362                 aCPolyArr->AddVertex(P, aDefNorm       , aNColor );
363               }
364               else
365                 aCPolyArr->AddVertex(P, aDefNorm, aNColor );
366             }
367             else
368               aCPolyArr->AddVertex( P, aNColor );
369           }
370           aPolyL->AddVertex ( P );
371           if ( i == 1 )
372             Start = P;
373         }
374         aPolyL->AddVertex ( Start );
375
376         // if IsExcludingOn then presentation must not be built by other builders
377         if ( IsExcludingOn() )
378           IDsToExclude.Add( aKey );
379       }
380       else if ( aType == MeshVS_ET_Volume )
381       {
382         if ( !aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
383           continue;
384
385         // iterate through faces of volume
386         for ( Standard_Integer k = aTopo->Lower(), last = aTopo->Upper(), normIndex = 1; k <= last; k++, normIndex++ )
387         {
388           const TColStd_SequenceOfInteger& aSeq = aTopo->Value( k );
389           Standard_Integer m = aSeq.Length(), ind;
390
391           // build polygon & polylines for current face
392           aCPolyArr->AddBound( m );
393           aPolyL->AddBound( m + 1 );
394           for ( Standard_Integer j = 1; j <= m; j++ )
395           {
396             ind = aSeq.Value( j );
397             P = gp_Pnt( aCoords( 3 * ind + 1 ),
398                         aCoords( 3 * ind + 2 ),
399                         aCoords( 3 * ind + 3 ) );
400             if ( myUseTexture )
401             {
402               Standard_Integer anId = aNodes( ind + 1 );
403               Standard_Real aTexCoord = myTextureCoords( anId );
404
405               // transform texture coordinate in accordance with number of colors specified
406               // by upper level and real size of Gl texture
407               // The Gl texture has border colors interpolated with the colors from the color map,
408               // thats why we need to shrink texture coordinates around the middle point to
409               // exclude areas where the map colors are interpolated with the borders color
410               double aWrapCoord = 1.0 / (2.0 * nbTextureColors) + aTexCoord * (nbColors - 1.0) / nbTextureColors;
411
412               if ( hasNormals )
413               {
414                 gp_Vec aNorm(aNormals->Value( 3 * i - 2 ),
415                              aNormals->Value( 3 * i - 1 ),
416                              aNormals->Value( 3 * i     ));
417                 // There are two "rows" of colors: user's invalid color at the top
418                 // of texture and line of map colors at the bottom of the texture.
419                 // Since the texture has borders, which are interpolated with the "rows" of colors
420                 // we should specify the 0.25 offset to get the correct texture color
421                 aNorm.SquareMagnitude() > aMin ?
422                   aCPolyArr->AddVertex(P, gp_Dir( aNorm ),
423                     gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ) :
424                   aCPolyArr->AddVertex(P, aDefNorm,
425                     gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
426               }
427               else
428                 aCPolyArr->AddVertex( P, aDefNorm,
429                   gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) );
430             }
431             else
432             {
433               GetColor( aNodes( ind + 1 ), aNColor );
434               if  ( IsReflect )
435               {
436                 // Simulating TelUpdateMaterial() from OpenGl_attri.c
437                 // to get the same colors in elemental and nodal color prs builders
438                 aNColor.SetValues(anColorRatio * aNColor.Red(),
439                                   anColorRatio * aNColor.Green(),
440                                   anColorRatio * aNColor.Blue(),
441                                   Quantity_TOC_RGB);
442
443                 if ( hasNormals )
444                 {
445                   gp_Vec aNorm(aNormals->Value( 3 * normIndex - 2 ),
446                     aNormals->Value( 3 * normIndex - 1 ),
447                     aNormals->Value( 3 * normIndex ));
448                   aNorm.SquareMagnitude() > aMin ?
449                     aCPolyArr->AddVertex( P, gp_Dir( aNorm ), aNColor ) :
450                   aCPolyArr->AddVertex( P, aDefNorm       , aNColor );
451                 }
452                 else
453                   aCPolyArr->AddVertex( P, aDefNorm, aNColor );
454               }
455               else
456                 aCPolyArr->AddVertex( P, aNColor );
457             }
458             aPolyL->AddVertex ( P );
459             if ( j == 1 )
460               Start = P;
461           }
462           aPolyL->AddVertex ( Start );
463         }
464
465         // if IsExcludingOn then presentation must not be built by other builders
466         if ( IsExcludingOn() )
467           IDsToExclude.Add( aKey );
468       }
469     }
470   } // for ( ...
471
472   Handle(Graphic3d_AspectFillArea3d) anAsp;
473
474 //  Aspect_InteriorStyle  aStyle;
475 //  Standard_Integer      aStyleInt;
476   Aspect_TypeOfLine     anEdgeType = Aspect_TOL_SOLID;
477   Standard_Integer      anEdgeInt;
478   Standard_Real         anEdgeWidth;
479   Quantity_Color        anInteriorColor;
480   Quantity_Color        anEdgeColor, aLineColor;
481   Standard_Boolean      aShowEdges = Standard_True;
482
483   aDrawer->GetColor  ( MeshVS_DA_InteriorColor, anInteriorColor );
484   aDrawer->GetColor  ( MeshVS_DA_EdgeColor, anEdgeColor );
485   aDrawer->GetColor  ( MeshVS_DA_BeamColor, aLineColor );
486   aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth );
487   aDrawer->GetBoolean( MeshVS_DA_ShowEdges, aShowEdges );
488
489   if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt ) )
490     anEdgeType = (Aspect_TypeOfLine) anEdgeInt;
491
492   if ( myUseTexture )
493   {
494     Handle(AIS_Drawer) anAISDrawer =  myParentMesh->Attributes();
495     if ( anAISDrawer.IsNull() )
496       return;
497
498     anAISDrawer->SetShadingAspect( new Prs3d_ShadingAspect() );
499     anAsp = anAISDrawer->ShadingAspect()->Aspect();
500     if ( anAsp.IsNull() )
501       return;
502
503     anAsp->SetFrontMaterial( aMaterial[ 0 ] );
504     anAsp->SetBackMaterial( aMaterial[ 1 ] );
505
506
507     Handle(Graphic3d_Texture2D) aTexture = CreateTexture();
508     if ( aTexture.IsNull() )
509       return;
510
511     anAsp->SetTextureMapOn();
512     anAsp->SetTextureMap( aTexture );
513     anAsp->SetInteriorColor( Quantity_NOC_WHITE );
514   }
515   else
516   {
517 //    if ( aDrawer->GetInteger ( MeshVS_DA_InteriorStyle, aStyleInt ) )
518 //      aStyle = (Aspect_InteriorStyle)aStyleInt;
519
520     anAsp = new Graphic3d_AspectFillArea3d (
521       Aspect_IS_SOLID, Quantity_NOC_GRAY, anEdgeColor,
522       anEdgeType, anEdgeWidth, aMaterial[ 0 ], aMaterial[ 1 ] );
523   }
524
525   anAsp->SetDistinguishOff();
526   anAsp->SetEdgeOff();
527
528   Handle(Graphic3d_AspectLine3d) anLAsp =
529     new Graphic3d_AspectLine3d( anEdgeColor, anEdgeType, anEdgeWidth );
530
531   Prs3d_Root::NewGroup ( Prs );
532   Handle(Graphic3d_Group) aGroup1 = Prs3d_Root::CurrentGroup ( Prs );
533
534   aGroup1->SetPrimitivesAspect( anAsp );
535   aGroup1->BeginPrimitives();
536   aGroup1->AddPrimitiveArray( aCPolyArr );
537   aGroup1->EndPrimitives();
538
539   if (aShowEdges)
540   {
541     Prs3d_Root::NewGroup ( Prs );
542     Handle(Graphic3d_Group) aGroup2 = Prs3d_Root::CurrentGroup ( Prs );
543
544     anAsp->SetEdgeOff();
545     anAsp->SetTextureMapOff();
546     aGroup2->SetPrimitivesAspect( anAsp );
547     aGroup2->SetPrimitivesAspect( anLAsp );
548     aGroup2->BeginPrimitives();
549     aGroup2->AddPrimitiveArray( aPolyL );
550     aGroup2->EndPrimitives();
551     anAsp->SetEdgeOn();
552   }
553 }
554
555 //================================================================
556 // Function : SetColors
557 // Purpose  :
558 //================================================================
559 void MeshVS_NodalColorPrsBuilder::SetColors (
560   const MeshVS_DataMapOfIntegerColor& theColorMap )
561 {
562   myNodeColorMap = theColorMap;
563 }
564
565 //================================================================
566 // Function : GetColors
567 // Purpose  :
568 //================================================================
569 const MeshVS_DataMapOfIntegerColor& MeshVS_NodalColorPrsBuilder::GetColors() const
570 {
571   return myNodeColorMap;
572 }
573
574 //================================================================
575 // Function : HasColors
576 // Purpose  :
577 //================================================================
578 Standard_Boolean MeshVS_NodalColorPrsBuilder::HasColors () const
579 {
580   return ( myNodeColorMap.Extent() >0 );
581 }
582
583 //================================================================
584 // Function : GetColor
585 // Purpose  :
586 //================================================================
587 Standard_Boolean MeshVS_NodalColorPrsBuilder::GetColor ( const Standard_Integer ID,
588                                                          Quantity_Color& theColor ) const
589 {
590   Standard_Boolean aRes = myNodeColorMap.IsBound ( ID );
591   if ( aRes )
592     theColor = myNodeColorMap.Find ( ID );
593   return aRes;
594 }
595
596 //================================================================
597 // Function : SetColor
598 // Purpose  :
599 //================================================================
600 void MeshVS_NodalColorPrsBuilder::SetColor ( const Standard_Integer theID,
601                                              const Quantity_Color& theCol )
602 {
603   Standard_Boolean aRes = myNodeColorMap.IsBound ( theID );
604   if ( aRes )
605     myNodeColorMap.ChangeFind ( theID ) = theCol;
606   else
607     myNodeColorMap.Bind ( theID, theCol );
608 }
609
610 //================================================================
611 // Function : UseTexture
612 // Purpose  : Specify whether texture must be used to build presentation
613 //================================================================
614 void MeshVS_NodalColorPrsBuilder::UseTexture( const Standard_Boolean theToUse )
615 {
616   myUseTexture = theToUse;
617   if ( myUseTexture )
618     myNodeColorMap.Clear();
619   else
620     myTextureColorMap.Clear();
621 }
622
623 //================================================================
624 // Function : IsUseTexture
625 // Purpose  : Verify whether texture is used to build presentation
626 //================================================================
627 Standard_Boolean MeshVS_NodalColorPrsBuilder::IsUseTexture() const
628 {
629   return myUseTexture;
630 }
631
632 //================================================================
633 // Function : SetColorMap
634 // Purpose  : Set colors to be used for texrture presentation.
635 //            Generate texture in accordance with given parameters
636 //================================================================
637 void MeshVS_NodalColorPrsBuilder::SetColorMap( const Aspect_SequenceOfColor& theColors )
638 {
639   myTextureColorMap = theColors;
640 }
641
642 //================================================================
643 // Function : GetColorMap
644 // Purpose  : Return colors used for texrture presentation
645 //================================================================
646 const Aspect_SequenceOfColor& MeshVS_NodalColorPrsBuilder::GetColorMap() const
647 {
648   return myTextureColorMap;
649 }
650
651 //================================================================
652 // Function : SetInvalidColor
653 // Purpose  : Set color representing invalid texture coordinate
654 //            (laying outside range [0, 1])
655 //================================================================
656 void MeshVS_NodalColorPrsBuilder::SetInvalidColor(
657   const Quantity_Color& theInvalidColor )
658 {
659   myInvalidColor = theInvalidColor;
660 }
661
662 //================================================================
663 // Function : GetInvalidColor
664 // Purpose  : Return color representing invalid texture coordinate
665 //            (laying outside range [0, 1])
666 //================================================================
667 Quantity_Color MeshVS_NodalColorPrsBuilder::GetInvalidColor() const
668 {
669   return myInvalidColor;
670 }
671
672 //================================================================
673 // Function : SetTextureCoords
674 // Purpose  : Specify correspondence between node IDs and texture
675 //            coordinates (range [0, 1])
676 //================================================================
677 void MeshVS_NodalColorPrsBuilder::SetTextureCoords (
678   const TColStd_DataMapOfIntegerReal& theMap )
679 {
680   myTextureCoords = theMap;
681 }
682
683 //================================================================
684 // Function : GetTextureCoords
685 // Purpose  : Get correspondence between node IDs and texture
686 //            coordinates (range [0, 1])
687 //================================================================
688 const TColStd_DataMapOfIntegerReal& MeshVS_NodalColorPrsBuilder::GetTextureCoords() const
689 {
690   return myTextureCoords;
691 }
692
693 //================================================================
694 // Function : SetTextureCoord
695 // Purpose  : Specify correspondence between node ID and texture
696 //            coordinate (range [0, 1])
697 //================================================================
698 void MeshVS_NodalColorPrsBuilder::SetTextureCoord( const Standard_Integer theID,
699                                                    const Standard_Real theCoord )
700 {
701   myTextureCoords.Bind( theID, theCoord );
702 }
703
704 //================================================================
705 // Function : GetTextureCoord
706 // Purpose  : Return correspondence between node IDs and texture
707 //            coordinate (range [0, 1])
708 //================================================================
709 Standard_Real MeshVS_NodalColorPrsBuilder::GetTextureCoord( const Standard_Integer theID )
710 {
711   return myTextureCoords.IsBound( theID ) ? myTextureCoords( theID ) : -1;
712 }
713
714 //================================================================
715 // Function : CreateTexture
716 // Purpose  : Create texture in accordance with myTextureColorMap
717 //================================================================
718 Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const
719 {
720   const Standard_Integer aColorsNb = myTextureColorMap.Length();
721   if (aColorsNb == 0)
722   {
723     return NULL;
724   }
725
726   Handle(PrsMgr_PresentationManager3d) aPrsMgr = GetPresentationManager();
727   if (aPrsMgr.IsNull())
728   {
729     return NULL;
730   }
731
732   // create and fill image with colors
733   Image_PixMap anImage;
734   if (!anImage.InitTrash (Image_PixMap::ImgRGBA, Standard_Size(getNearestPow2 (aColorsNb)), 2))
735   {
736     return NULL;
737   }
738
739   anImage.SetTopDown (false);
740   Image_PixMapData<Image_ColorRGBA>& aData = anImage.EditData<Image_ColorRGBA>();
741   for (Standard_Size aCol = 0; aCol < Standard_Size(aColorsNb); ++aCol)
742   {
743     const Quantity_Color& aSrcColor = myTextureColorMap.Value (Standard_Integer(aCol) + 1);
744     Image_ColorRGBA& aColor = aData.ChangeValue (0, aCol);
745     aColor.r() = int(255.0 * aSrcColor.Red());
746     aColor.g() = int(255.0 * aSrcColor.Green());
747     aColor.b() = int(255.0 * aSrcColor.Blue());
748     aColor.a() = 0xFF;
749   }
750
751   // fill padding bytes
752   const Quantity_Color& aLastColorSrc = myTextureColorMap.Last();
753   const Image_ColorRGBA aLastColor =
754   {{
755     int(255.0 * aLastColorSrc.Red()),
756     int(255.0 * aLastColorSrc.Green()),
757     int(255.0 * aLastColorSrc.Blue()),
758     0xFF
759   }};
760
761   // fill second row
762   for (Standard_Size aCol = (Standard_Size )aColorsNb; aCol < anImage.SizeX(); ++aCol)
763   {
764     aData.ChangeValue (0, aCol) = aLastColor;
765   }
766
767   const Image_ColorRGBA anInvalidColor =
768   {{
769     int(255.0 * myInvalidColor.Red()),
770     int(255.0 * myInvalidColor.Green()),
771     int(255.0 * myInvalidColor.Blue()),
772     0xFF
773   }};
774   for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
775   {
776     aData.ChangeValue (1, aCol) = anInvalidColor;
777   }
778
779   // create texture
780   return new MeshVS_ImageTexture2D (aPrsMgr->StructureManager(), anImage);
781 }