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