0023024: Update headers of OCCT files
[occt.git] / src / MeshVS / MeshVS_ElementalColorPrsBuilder.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_ElementalColorPrsBuilder.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_MapOfInteger.hxx>
39 #include <TColStd_PackedMapOfInteger.hxx>
40 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
41 #include <TColStd_ListIteratorOfListOfInteger.hxx>
42 #include <TColStd_Array1OfReal.hxx>
43 #include <TColStd_SequenceOfInteger.hxx>
44 #include <TColStd_HArray1OfReal.hxx>
45 #include <TColStd_HPackedMapOfInteger.hxx>
46
47 #include <MeshVS_DisplayModeFlags.hxx>
48 #include <MeshVS_DataSource.hxx>
49 #include <MeshVS_Mesh.hxx>
50 #include <MeshVS_DataMapOfColorMapOfInteger.hxx>
51 #include <MeshVS_DataMapOfTwoColorsMapOfInteger.hxx>
52 #include <MeshVS_Drawer.hxx>
53 #include <MeshVS_DrawerAttribute.hxx>
54 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors.hxx>
55 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerColor.hxx>
56 #include <MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger.hxx>
57 #include <MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx>
58 #include <MeshVS_MeshPrsBuilder.hxx>
59 #include <MeshVS_Buffer.hxx>
60
61
62 //================================================================
63 // Function : Constructor MeshVS_ElementalColorPrsBuilder
64 // Purpose  :
65 //================================================================
66 MeshVS_ElementalColorPrsBuilder::MeshVS_ElementalColorPrsBuilder
67   ( const Handle(MeshVS_Mesh)& Parent,
68     const MeshVS_DisplayModeFlags& Flags,
69     const Handle (MeshVS_DataSource)& DS,
70     const Standard_Integer Id,
71     const MeshVS_BuilderPriority& Priority )
72 : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority )
73 {
74   SetExcluding ( Standard_True );
75 }
76
77 //================================================================
78 // Function : Build
79 // Purpose  :
80 //================================================================
81 void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
82                                               const TColStd_PackedMapOfInteger& IDs,
83                                               TColStd_PackedMapOfInteger& IDsToExclude,
84                                               const Standard_Boolean IsElement,
85                                               const Standard_Integer DisplayMode) const
86 {
87   Handle (MeshVS_DataSource) aSource = GetDataSource();
88   Handle (MeshVS_Drawer)     aDrawer = GetDrawer();
89
90   if ( aSource.IsNull() || aDrawer.IsNull() )
91     return;
92
93   Standard_Integer aMaxFaceNodes;
94   if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) && aMaxFaceNodes<=0 )
95     return;
96
97   MeshVS_DataMapOfIntegerColor* anElemColorMap = (MeshVS_DataMapOfIntegerColor*) &myElemColorMap1;
98   MeshVS_DataMapOfIntegerTwoColors* anElemTwoColorsMap = (MeshVS_DataMapOfIntegerTwoColors*)&myElemColorMap2;
99
100   MeshVS_DataMapOfColorMapOfInteger     aColorsOfElements;
101   MeshVS_DataMapOfTwoColorsMapOfInteger aTwoColorsOfElements;
102
103   MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
104   TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*aMaxFaceNodes);
105   Standard_Integer NbNodes;
106   MeshVS_EntityType aType;
107
108   if ( !( DisplayMode & GetFlags() ) || !IsElement ||
109        ( myElemColorMap1.IsEmpty() && myElemColorMap2.IsEmpty() ) )
110     return;
111
112   // subtract the hidden elements and ids to exclude (to minimise allocated memory)
113   TColStd_PackedMapOfInteger anIDs;
114   anIDs.Assign( IDs );
115   Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
116   if ( !aHiddenElems.IsNull() )
117     anIDs.Subtract( aHiddenElems->Map() );
118   anIDs.Subtract( IDsToExclude );
119
120   // STEP 0: We looking for two colored elements, who has equal two colors and move it
121   // to map of elements with one assigned color
122   TColStd_ListOfInteger aColorOne;
123   for ( MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors anIter ( *anElemTwoColorsMap ); anIter.More(); anIter.Next () )
124   {
125     Standard_Integer aKey   = anIter.Key ();
126     MeshVS_TwoColors aValue = anIter.Value ();
127     Quantity_Color   aCol1, aCol2;
128     ExtractColors ( aValue, aCol1, aCol2 );
129     if ( aCol1 == aCol2 )
130     {
131       aColorOne.Append ( aKey );
132       anElemColorMap->Bind ( aKey, aCol1 );
133     }
134   }
135
136   for ( TColStd_ListIteratorOfListOfInteger aLIter ( aColorOne ); aLIter.More(); aLIter.Next() )
137     anElemTwoColorsMap->UnBind ( aLIter.Value() );
138
139   // The map is to resort itself by colors.
140   // STEP 1: We start sorting elements with one assigned color
141   for ( MeshVS_DataMapIteratorOfDataMapOfIntegerColor anIterM ( *anElemColorMap ); anIterM.More(); anIterM.Next () )
142   {
143     Standard_Integer aMKey = anIterM.Key ();
144     // The ID of current element
145     Standard_Boolean IsExist = Standard_False;
146     for ( MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger anIterC ( aColorsOfElements );
147           anIterC.More() && !IsExist; anIterC.Next () )
148       if ( anIterC.Key()==anIterM.Value() )
149       {
150         TColStd_MapOfInteger& aChangeValue = (TColStd_MapOfInteger&) anIterC.Value();
151         aChangeValue.Add ( aMKey );
152         IsExist = Standard_True;
153       }
154
155     if ( !IsExist )
156     {
157       TColStd_MapOfInteger aNewMap; aNewMap.Add ( aMKey );
158       aColorsOfElements.Bind ( anIterM.Value(), aNewMap );
159     }
160   }
161
162   // STEP 2: We start sorting elements with two assigned colors
163   for ( MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors anIterM2 ( *anElemTwoColorsMap ); anIterM2.More();
164         anIterM2.Next () )
165   {
166     Standard_Integer aMKey = anIterM2.Key ();
167     // The ID of current element
168     Standard_Boolean IsExist = Standard_False;
169     for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger anIterC2 ( aTwoColorsOfElements );
170           anIterC2.More() && !IsExist; anIterC2.Next () )
171       if ( IsEqual ( anIterC2.Key(), anIterM2.Value() ) )
172       {
173         TColStd_MapOfInteger& aChangeValue = (TColStd_MapOfInteger&) anIterC2.Value();
174         aChangeValue.Add ( aMKey );
175         IsExist = Standard_True;
176       }
177
178     if ( !IsExist )
179     {
180       TColStd_MapOfInteger aNewMap; aNewMap.Add ( aMKey );
181       aTwoColorsOfElements.Bind ( anIterM2.Value(), aNewMap );
182     }
183   }
184
185   //Now we are ready to draw faces with equal colors
186   Aspect_InteriorStyle aStyle;
187   Standard_Integer     aStyleInt;
188   Aspect_TypeOfLine    anEdgeType = Aspect_TOL_SOLID;
189   Aspect_TypeOfLine    aLineType = Aspect_TOL_SOLID;
190   Standard_Integer     anEdgeInt, aLineInt;
191   Standard_Real        anEdgeWidth, aLineWidth;
192   Quantity_Color       anInteriorColor;
193   Quantity_Color       anEdgeColor, aLineColor;
194   Standard_Boolean     anEdgeOn = Standard_True, IsReflect = Standard_False,
195                        IsMeshSmoothShading = Standard_False;
196
197   aDrawer->GetColor  ( MeshVS_DA_InteriorColor, anInteriorColor );
198   aDrawer->GetColor  ( MeshVS_DA_EdgeColor, anEdgeColor );
199   aDrawer->GetColor  ( MeshVS_DA_BeamColor, aLineColor );
200   aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth );
201   aDrawer->GetDouble ( MeshVS_DA_BeamWidth, aLineWidth );
202   aDrawer->GetBoolean( MeshVS_DA_ShowEdges, anEdgeOn );
203   aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect );
204   aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
205
206   if ( aDrawer->GetInteger ( MeshVS_DA_InteriorStyle, aStyleInt) )
207     aStyle = (Aspect_InteriorStyle) aStyleInt;
208
209   if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt) )
210     anEdgeType = (Aspect_TypeOfLine) anEdgeInt;
211
212   if ( aDrawer->GetInteger ( MeshVS_DA_BeamType, aLineInt) )
213     aLineType = (Aspect_TypeOfLine) aLineInt;
214
215   Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
216   Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0;
217   TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
218   for( ; it.More(); it.Next() )
219   {
220     Standard_Integer aKey = it.Key();
221     if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
222         MeshVS_MeshPrsBuilder::HowManyPrimitives
223           ( aTopo, Standard_True, Standard_False, NbNodes,
224             PolygonVerticesFor3D, PolygonBoundsFor3D );
225   }
226
227   Graphic3d_MaterialAspect aMaterial[2];
228   Standard_Integer i;
229   for ( i=0; i<2; i++ )
230   {
231     // OCC20644 "plastic" is most suitable here, as it is "non-physic"
232     // so TelUpdateMaterial() from OpenGl_attri.c uses the interior
233     // color from AspectFillArea3d to calculate all material colors
234     aMaterial[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC );
235
236     // OCC21720 For single-colored elements turning all material components off is a good idea,
237     // as anyhow the normals are not computed and the lighting will be off,
238     // the element color will be taken from Graphic3d_AspectFillArea3d's interior color,
239     // and there is no need to spend time on updating material properties 
240     if ( !IsReflect )
241     {
242       aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
243       aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
244       aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
245       aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_EMISSION);
246     }
247     else
248     {
249       // OCC20644 This stuff is important in order for elemental and nodal colors
250       // to produce similar visual impression and also to make colors match
251       // those in the color scale most exactly (the sum of all reflection 
252       // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder
253       // class for more explanations.
254       aMaterial[i].SetAmbient( .5 );
255       aMaterial[i].SetDiffuse( .5 );
256       aMaterial[i].SetSpecular( 0. );
257       aMaterial[i].SetEmissive( 0. );
258     }
259   }
260
261   // Draw elements with one color
262   for ( MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger aColIter ( aColorsOfElements ); aColIter.More();
263         aColIter.Next() )
264   {
265     Standard_Integer aSize = aColIter.Value().Extent();
266     if ( aSize<=0 )
267       continue;
268
269     TColStd_PackedMapOfInteger aCustomElements;
270
271     Prs3d_Root::NewGroup ( Prs );
272     Handle ( Graphic3d_Group ) aGGroup = Prs3d_Root::CurrentGroup ( Prs );
273     Prs3d_Root::NewGroup ( Prs );
274     Handle ( Graphic3d_Group ) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
275
276     Handle (Graphic3d_ArrayOfPolygons) aPolyGArr = new Graphic3d_ArrayOfPolygons
277       ( aMaxFaceNodes*aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D, 0, IsReflect );
278     Standard_Boolean IsPolyG = Standard_False;
279
280     Handle (Graphic3d_ArrayOfPolylines) aPolyLArr = new Graphic3d_ArrayOfPolylines
281       ( 2*aSize, aSize );
282     Standard_Boolean IsPolyL = Standard_False;
283
284     // OCC20644 NOTE: aColIter.Key() color is then scaled by TelUpdateMaterial() in OpenGl_attri.c
285     // using the material reflection coefficients. This affects the visual result.
286     Handle(Graphic3d_AspectFillArea3d) anAsp =
287       new Graphic3d_AspectFillArea3d ( Aspect_IS_SOLID, aColIter.Key(), anEdgeColor,
288                                        anEdgeType, anEdgeWidth, aMaterial[0], aMaterial[1] );
289
290     Handle(Graphic3d_AspectLine3d) anLAsp =
291       new Graphic3d_AspectLine3d ( aColIter.Key(), aLineType, aLineWidth );
292
293     anAsp->SetDistinguishOff ();
294     anAsp->SetInteriorColor ( aColIter.Key() );
295     if (anEdgeOn)
296       anAsp->SetEdgeOn();
297     else
298       anAsp->SetEdgeOff();
299
300     for( it.Reset(); it.More(); it.Next() )
301     {
302       Standard_Integer aKey = it.Key();
303       if( aColIter.Value().Contains( aKey ) )
304       {
305         if ( !aSource->GetGeom  ( aKey, Standard_True, aCoords, NbNodes, aType ) )
306           continue;
307
308         if( aType == MeshVS_ET_Face )
309         {
310           aPolyGArr->AddBound ( NbNodes );
311           if( IsExcludingOn() )
312             IDsToExclude.Add( aKey );
313         }
314         else if( aType == MeshVS_ET_Link )
315         {
316           aPolyLArr->AddBound ( NbNodes );
317           if( IsExcludingOn() )
318             IDsToExclude.Add( aKey );
319         }
320         else if( aType == MeshVS_ET_Volume )
321         {
322           if( IsExcludingOn() )
323             IDsToExclude.Add( aKey );
324           if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
325           {
326             MeshVS_MeshPrsBuilder::AddVolumePrs( aTopo, aCoords, NbNodes, aPolyGArr, IsReflect, Standard_False, Standard_False, 1.0 );
327             IsPolyG = Standard_True;
328           }
329           else
330             continue;
331         }
332         else
333         {
334           aCustomElements.Add( aKey );
335           continue;
336         }
337
338         // Preparing normal(s) to show reflections if requested
339         Handle(TColStd_HArray1OfReal) aNormals;
340         Standard_Boolean hasNormals = IsReflect && aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals );
341
342         // Adding vertices (with normals if necessary)
343         for ( i=1; i<=NbNodes; i++ )
344           if ( aType == MeshVS_ET_Face )
345           {
346             if ( IsReflect )
347             {
348               hasNormals ? aPolyGArr->AddVertex ( aCoords(3 * i - 2), 
349                                                   aCoords(3 * i - 1), 
350                                                   aCoords(3 * i    ),
351                                                   aNormals->Value(3 * i - 2), 
352                                                   aNormals->Value(3 * i - 1), 
353                                                   aNormals->Value(3 * i    ) ) :
354                            aPolyGArr->AddVertex ( aCoords(3 * i - 2), 
355                                                   aCoords(3 * i - 1), 
356                                                   aCoords(3 * i    ),
357                                                   0., 
358                                                   0., 
359                                                   1. );
360             }
361             else
362               aPolyGArr->AddVertex ( aCoords(3 * i - 2), 
363                                      aCoords(3 * i - 1), 
364                                      aCoords(3 * i    ) );
365             IsPolyG = Standard_True;
366           }
367           else if ( aType == MeshVS_ET_Link )
368           {
369             aPolyLArr->AddVertex ( aCoords(3*i-2), aCoords(3*i-1), aCoords(3*i) );
370             IsPolyL = Standard_True;
371           }
372       }
373     }
374
375     if ( IsPolyG )
376     {
377       aGGroup->SetPrimitivesAspect ( anAsp );
378       aGGroup->BeginPrimitives();
379       aGGroup->AddPrimitiveArray ( aPolyGArr );
380       aGGroup->EndPrimitives();
381     }
382     if ( IsPolyL )
383     {
384       anAsp->SetEdgeOff();
385       aLGroup->SetPrimitivesAspect ( anAsp );
386       aLGroup->SetPrimitivesAspect ( anLAsp );
387       aLGroup->BeginPrimitives();
388       aLGroup->AddPrimitiveArray ( aPolyLArr );
389       aLGroup->EndPrimitives();
390       if (anEdgeOn)
391         anAsp->SetEdgeOn();
392       else
393         anAsp->SetEdgeOff();
394     }
395
396     if( !aCustomElements.IsEmpty() )
397       CustomBuild( Prs, aCustomElements, IDsToExclude, DisplayMode );
398   }
399
400   Graphic3d_MaterialAspect aMaterial2[2];
401   for ( i=0; i<2; i++ )
402   {
403     // OCC20644 "plastic" is most suitable here, as it is "non-physic"
404     // so TelUpdateMaterial() from OpenGl_attri.c uses the interior
405     // color from AspectFillArea3d to calculate all material colors
406     aMaterial2[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC );
407
408     if ( !IsReflect )
409     {
410       // OCC21720 Cannot turn ALL material components off, as such a material
411       // would be ignored by TelUpdateMaterial(), but we need it in order
412       // to have different materials for front and back sides!
413       // Instead, trying to make material color "nondirectional" with 
414       // only ambient component on.
415       aMaterial2[i].SetReflectionModeOn ( Graphic3d_TOR_AMBIENT );
416       aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_DIFFUSE );
417       aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_SPECULAR );
418       aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_EMISSION );
419       aMaterial2[i].SetAmbient ( 1. );
420       aMaterial2[i].SetDiffuse ( 0. );
421       aMaterial2[i].SetSpecular( 0. );
422       aMaterial2[i].SetEmissive( 0. );
423     }
424     else
425     {
426       // OCC20644 This stuff is important in order for elemental and nodal colors
427       // to produce similar visual impression and also to make colors match
428       // those in the color scale most exactly (the sum of all reflection 
429       // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder
430       // class for more explanations.
431       aMaterial2[i].SetAmbient( .5 );
432       aMaterial2[i].SetDiffuse( .5 );
433       aMaterial2[i].SetSpecular( 0. );
434       aMaterial2[i].SetEmissive( 0. );
435     }
436   }
437
438   // Draw faces with two color
439   for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger aColIter2 ( aTwoColorsOfElements );
440         aColIter2.More(); aColIter2.Next() )
441   {
442     Prs3d_Root::NewGroup ( Prs );
443     Handle ( Graphic3d_Group ) aGroup2 = Prs3d_Root::CurrentGroup ( Prs );
444
445     Standard_Integer aSize = aColIter2.Value().Extent();
446     if ( aSize<=0 )
447       continue;
448
449 #ifdef _POLYGONES_
450     Handle (Graphic3d_ArrayOfPolygons) aPolyArr = new Graphic3d_ArrayOfPolygons
451       ( aMaxFaceNodes*aSize, aSize, 0, IsReflect );
452 #endif
453
454     MeshVS_TwoColors aTC = aColIter2.Key();
455     Quantity_Color aMyIntColor, aMyBackColor;
456     ExtractColors ( aTC, aMyIntColor, aMyBackColor );
457
458     // OCC20644 NOTE: aMyIntColor color is then scaled by TelUpdateMaterial() in OpenGl_attri.c
459     // using the material reflection coefficients. This affects the visual result.
460     Handle(Graphic3d_AspectFillArea3d) anAsp =
461       new Graphic3d_AspectFillArea3d ( Aspect_IS_SOLID, aMyIntColor, anEdgeColor,
462                                          anEdgeType, anEdgeWidth, aMaterial2[0], aMaterial2[1] );
463     anAsp->SetDistinguishOn ();
464     anAsp->SetInteriorColor ( aMyIntColor );
465     anAsp->SetBackInteriorColor ( aMyBackColor );
466     if (anEdgeOn)
467       anAsp->SetEdgeOn();
468     else
469       anAsp->SetEdgeOff();
470
471     aGroup2->SetPrimitivesAspect ( anAsp );
472     aGroup2->BeginPrimitives();
473
474     for( it.Reset(); it.More(); it.Next() )
475     {
476       Standard_Integer aKey = it.Key();
477       if( aColIter2.Value().Contains( aKey ) )
478       {
479         if ( !aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
480           continue;
481
482         if( IsExcludingOn() )
483           IDsToExclude.Add( aKey );
484
485         if ( aType == MeshVS_ET_Face && NbNodes > 0 )
486         {
487           // Preparing normal(s) to show reflections if requested
488           Handle(TColStd_HArray1OfReal) aNormals;
489           // OCC21720 Always passing normals to OpenGL to make materials work
490           // For OpenGL: "No normals" -> "No lighting" -> "no materials taken into account"
491           Standard_Boolean hasNormals = /*IsReflect &&*/
492             aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals );
493
494 #ifdef _POLYGONES_
495           aPolyArr->AddBound ( NbNodes );
496 #else
497           Graphic3d_Array1OfVertex aVertArr ( 1, NbNodes );
498 #endif
499
500           for ( i=1; i<=NbNodes; i++ )
501           {
502 #ifdef _POLYGONES_
503             if ( IsReflect )
504             {
505               hasNormals ? aPolyArr->AddVertex ( aCoords(3 * i - 2), 
506                                                  aCoords(3 * i - 1), 
507                                                  aCoords(3 * i    ),
508                                                  aNormals->Value(3 * i - 2), 
509                                                  aNormals->Value(3 * i - 1), 
510                                                  aNormals->Value(3 * i    ) ) :
511                            aPolyArr->AddVertex ( aCoords(3 * i - 2), 
512                                                  aCoords(3 * i - 1), 
513                                                  aCoords(3 * i    ),
514                                                  0., 
515                                                  0., 
516                                                  1. );
517             }
518             else
519               aPolyArr->AddVertex ( aCoords(3*i-2), 
520                                     aCoords(3*i-1), 
521                                     aCoords(3*i  ) );
522 #else
523             if ( IsReflect )
524             {
525               aVertArr (i) = hasNormals ? Graphic3d_VertexN( aCoords(3 * i - 2), 
526                                                              aCoords(3 * i - 1), 
527                                                              aCoords(3 * i    ),
528                                                              aNormals->Value(3 * i - 2), 
529                                                              aNormals->Value(3 * i - 1), 
530                                                              aNormals->Value(3 * i    ),
531                                                              Standard_False ) :
532                                             Graphic3d_VertexN( aCoords(3 * i - 2), 
533                                                              aCoords(3 * i - 1), 
534                                                              aCoords(3 * i    ),
535                                                              0., 
536                                                              0., 
537                                                              1.,
538                                                              Standard_False );
539                                                                                  
540             }
541             else
542               Graphic3d_Vertex ( aCoords(3 * i - 2), 
543                                  aCoords(3 * i - 1), 
544                                  aCoords(3 * i    ) );
545 #endif
546           }
547
548
549 #ifndef _POLYGONES_
550           aGroup2->Polygon ( aVertArr );
551 #endif
552         }
553       }
554     }
555 #ifdef _POLYGONES_
556     aGroup2->AddPrimitiveArray ( aPolyArr );
557 #endif
558     aGroup2->EndPrimitives();
559   }
560 }
561
562 //================================================================
563 // Function : SetColors
564 // Purpose  :
565 //================================================================
566 void MeshVS_ElementalColorPrsBuilder::SetColors1 ( const MeshVS_DataMapOfIntegerColor& theColorMap )
567 {
568   myElemColorMap1 = theColorMap;
569 }
570
571 //================================================================
572 // Function : GetColors
573 // Purpose  :
574 //================================================================
575 const MeshVS_DataMapOfIntegerColor& MeshVS_ElementalColorPrsBuilder::GetColors1 () const
576 {
577   return myElemColorMap1;
578 }
579
580 //================================================================
581 // Function : HasColors1
582 // Purpose  :
583 //================================================================
584 Standard_Boolean MeshVS_ElementalColorPrsBuilder::HasColors1 () const
585 {
586   return ( myElemColorMap1.Extent() >0 );
587 }
588
589 //================================================================
590 // Function : GetColor1
591 // Purpose  :
592 //================================================================
593 Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor1 ( const Standard_Integer ID,
594                                                               Quantity_Color& theColor ) const
595 {
596   Standard_Boolean aRes = myElemColorMap1.IsBound ( ID );
597   if ( aRes )
598     theColor = myElemColorMap1.Find ( ID );
599
600   return aRes;
601 }
602
603 //================================================================
604 // Function : SetColor1
605 // Purpose  :
606 //================================================================
607 void MeshVS_ElementalColorPrsBuilder::SetColor1 ( const Standard_Integer theID,
608                                                   const Quantity_Color& theCol )
609 {
610   Standard_Boolean aRes = myElemColorMap1.IsBound ( theID );
611   if ( aRes )
612     myElemColorMap1.ChangeFind ( theID ) = theCol;
613   else
614     myElemColorMap1.Bind ( theID, theCol );
615 }
616
617 //================================================================
618 // Function : SetColors2
619 // Purpose  :
620 //================================================================
621 void MeshVS_ElementalColorPrsBuilder::SetColors2 ( const MeshVS_DataMapOfIntegerTwoColors& theColorMap )
622 {
623   myElemColorMap2 = theColorMap;
624 }
625
626 //================================================================
627 // Function : GetColors2
628 // Purpose  :
629 //================================================================
630 const MeshVS_DataMapOfIntegerTwoColors& MeshVS_ElementalColorPrsBuilder::GetColors2 () const
631 {
632   return myElemColorMap2;
633 }
634
635 //================================================================
636 // Function : HasColors2
637 // Purpose  :
638 //================================================================
639 Standard_Boolean MeshVS_ElementalColorPrsBuilder::HasColors2 () const
640 {
641   return (myElemColorMap2.Extent()>0);
642 }
643
644 //================================================================
645 // Function : GetColor2
646 // Purpose  :
647 //================================================================
648 Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor2 ( const Standard_Integer ID,
649                                                               MeshVS_TwoColors& theColor ) const
650 {
651   Standard_Boolean aRes = myElemColorMap2.IsBound ( ID );
652   if ( aRes )
653     theColor = myElemColorMap2.Find ( ID );
654
655   return aRes;
656 }
657
658 //================================================================
659 // Function : GetColor2
660 // Purpose  :
661 //================================================================
662 Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor2 ( const Standard_Integer ID,
663                                                               Quantity_Color& theColor1,
664                                                               Quantity_Color& theColor2 ) const
665 {
666   MeshVS_TwoColors aTC;
667   Standard_Boolean aRes = GetColor2 ( ID, aTC );
668   if ( aRes)
669     ExtractColors ( aTC, theColor1, theColor2 );
670   return aRes;
671 }
672
673 //================================================================
674 // Function : SetColor2
675 // Purpose  :
676 //================================================================
677 void MeshVS_ElementalColorPrsBuilder::SetColor2 ( const Standard_Integer theID,
678                                                   const Quantity_Color& theCol1,
679                                                   const Quantity_Color& theCol2 )
680 {
681   SetColor2 ( theID, BindTwoColors ( theCol1, theCol2 ) );
682 }
683
684 //================================================================
685 // Function : SetColor2
686 // Purpose  :
687 //================================================================
688 void MeshVS_ElementalColorPrsBuilder::SetColor2 ( const Standard_Integer theID,
689                                                   const MeshVS_TwoColors& theCol )
690 {
691   Standard_Boolean aRes = myElemColorMap2.IsBound ( theID );
692   if ( aRes )
693     myElemColorMap2.ChangeFind ( theID ) = theCol;
694   else
695     myElemColorMap2.Bind ( theID, theCol );
696 }