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