1 // Created on: 2003-11-12
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 #include <Graphic3d_ArrayOfPolygons.hxx>
18 #include <Graphic3d_ArrayOfPolylines.hxx>
19 #include <Graphic3d_ArrayOfSegments.hxx>
20 #include <Graphic3d_ArrayOfTriangles.hxx>
21 #include <Graphic3d_AspectFillArea3d.hxx>
22 #include <Graphic3d_AspectLine3d.hxx>
23 #include <Graphic3d_Group.hxx>
24 #include <MeshVS_Buffer.hxx>
25 #include <MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx>
26 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerColor.hxx>
27 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors.hxx>
28 #include <MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger.hxx>
29 #include <MeshVS_DataMapOfColorMapOfInteger.hxx>
30 #include <MeshVS_DataMapOfTwoColorsMapOfInteger.hxx>
31 #include <MeshVS_DataSource.hxx>
32 #include <MeshVS_DisplayModeFlags.hxx>
33 #include <MeshVS_Drawer.hxx>
34 #include <MeshVS_DrawerAttribute.hxx>
35 #include <MeshVS_ElementalColorPrsBuilder.hxx>
36 #include <MeshVS_HArray1OfSequenceOfInteger.hxx>
37 #include <MeshVS_Mesh.hxx>
38 #include <MeshVS_MeshPrsBuilder.hxx>
39 #include <Prs3d_LineAspect.hxx>
40 #include <Prs3d_Presentation.hxx>
41 #include <Prs3d_Root.hxx>
42 #include <Prs3d_ShadingAspect.hxx>
43 #include <Quantity_Color.hxx>
44 #include <Standard_Type.hxx>
45 #include <TColStd_Array1OfReal.hxx>
46 #include <TColStd_HArray1OfReal.hxx>
47 #include <TColStd_HPackedMapOfInteger.hxx>
48 #include <TColStd_ListIteratorOfListOfInteger.hxx>
49 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
50 #include <TColStd_MapOfInteger.hxx>
51 #include <TColStd_PackedMapOfInteger.hxx>
52 #include <TColStd_SequenceOfInteger.hxx>
54 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_ElementalColorPrsBuilder,MeshVS_PrsBuilder)
56 //================================================================
57 // Function : Constructor MeshVS_ElementalColorPrsBuilder
59 //================================================================
60 MeshVS_ElementalColorPrsBuilder::MeshVS_ElementalColorPrsBuilder
61 ( const Handle(MeshVS_Mesh)& Parent,
62 const MeshVS_DisplayModeFlags& Flags,
63 const Handle (MeshVS_DataSource)& DS,
64 const Standard_Integer Id,
65 const MeshVS_BuilderPriority& Priority )
66 : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority )
68 SetExcluding ( Standard_True );
71 //================================================================
74 //================================================================
75 void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
76 const TColStd_PackedMapOfInteger& IDs,
77 TColStd_PackedMapOfInteger& IDsToExclude,
78 const Standard_Boolean IsElement,
79 const Standard_Integer DisplayMode) const
81 Handle (MeshVS_DataSource) aSource = GetDataSource();
82 Handle (MeshVS_Drawer) aDrawer = GetDrawer();
84 if ( aSource.IsNull() || aDrawer.IsNull() )
87 Standard_Integer aMaxFaceNodes;
88 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) && aMaxFaceNodes<=0 )
91 MeshVS_DataMapOfIntegerColor* anElemColorMap = (MeshVS_DataMapOfIntegerColor*) &myElemColorMap1;
92 MeshVS_DataMapOfIntegerTwoColors* anElemTwoColorsMap = (MeshVS_DataMapOfIntegerTwoColors*)&myElemColorMap2;
94 MeshVS_DataMapOfColorMapOfInteger aColorsOfElements;
95 MeshVS_DataMapOfTwoColorsMapOfInteger aTwoColorsOfElements;
97 MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
98 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*aMaxFaceNodes);
99 Standard_Integer NbNodes;
100 MeshVS_EntityType aType;
102 if ( !( DisplayMode & GetFlags() ) || !IsElement ||
103 ( myElemColorMap1.IsEmpty() && myElemColorMap2.IsEmpty() ) )
106 // subtract the hidden elements and ids to exclude (to minimise allocated memory)
107 TColStd_PackedMapOfInteger anIDs;
109 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
110 if ( !aHiddenElems.IsNull() )
111 anIDs.Subtract( aHiddenElems->Map() );
112 anIDs.Subtract( IDsToExclude );
114 // STEP 0: We looking for two colored elements, who has equal two colors and move it
115 // to map of elements with one assigned color
116 TColStd_ListOfInteger aColorOne;
117 for ( MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors anIter ( *anElemTwoColorsMap ); anIter.More(); anIter.Next () )
119 Standard_Integer aKey = anIter.Key ();
120 MeshVS_TwoColors aValue = anIter.Value ();
121 Quantity_Color aCol1, aCol2;
122 ExtractColors ( aValue, aCol1, aCol2 );
123 if ( aCol1 == aCol2 )
125 aColorOne.Append ( aKey );
126 anElemColorMap->Bind ( aKey, aCol1 );
130 for ( TColStd_ListIteratorOfListOfInteger aLIter ( aColorOne ); aLIter.More(); aLIter.Next() )
131 anElemTwoColorsMap->UnBind ( aLIter.Value() );
133 // The map is to resort itself by colors.
134 // STEP 1: We start sorting elements with one assigned color
135 for ( MeshVS_DataMapIteratorOfDataMapOfIntegerColor anIterM ( *anElemColorMap ); anIterM.More(); anIterM.Next () )
137 Standard_Integer aMKey = anIterM.Key ();
138 // The ID of current element
139 Standard_Boolean IsExist = Standard_False;
140 for ( MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger anIterC ( aColorsOfElements );
141 anIterC.More() && !IsExist; anIterC.Next () )
142 if ( anIterC.Key()==anIterM.Value() )
144 TColStd_MapOfInteger& aChangeValue = (TColStd_MapOfInteger&) anIterC.Value();
145 aChangeValue.Add ( aMKey );
146 IsExist = Standard_True;
151 TColStd_MapOfInteger aNewMap; aNewMap.Add ( aMKey );
152 aColorsOfElements.Bind ( anIterM.Value(), aNewMap );
156 // STEP 2: We start sorting elements with two assigned colors
157 for ( MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors anIterM2 ( *anElemTwoColorsMap ); anIterM2.More();
160 Standard_Integer aMKey = anIterM2.Key ();
161 // The ID of current element
162 Standard_Boolean IsExist = Standard_False;
163 for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger anIterC2 ( aTwoColorsOfElements );
164 anIterC2.More() && !IsExist; anIterC2.Next () )
165 if ( IsEqual ( anIterC2.Key(), anIterM2.Value() ) )
167 TColStd_MapOfInteger& aChangeValue = (TColStd_MapOfInteger&) anIterC2.Value();
168 aChangeValue.Add ( aMKey );
169 IsExist = Standard_True;
174 TColStd_MapOfInteger aNewMap; aNewMap.Add ( aMKey );
175 aTwoColorsOfElements.Bind ( anIterM2.Value(), aNewMap );
179 //Now we are ready to draw faces with equal colors
180 Aspect_TypeOfLine anEdgeType = Aspect_TOL_SOLID;
181 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
182 Standard_Integer anEdgeInt, aLineInt;
183 Standard_Real anEdgeWidth, aLineWidth;
184 Quantity_Color anInteriorColor;
185 Quantity_Color anEdgeColor, aLineColor;
186 Standard_Boolean anEdgeOn = Standard_True, IsReflect = Standard_False,
187 IsMeshSmoothShading = Standard_False;
188 Standard_Boolean toSupressBackFaces = Standard_False;
190 aDrawer->GetColor ( MeshVS_DA_InteriorColor, anInteriorColor );
191 aDrawer->GetColor ( MeshVS_DA_EdgeColor, anEdgeColor );
192 aDrawer->GetColor ( MeshVS_DA_BeamColor, aLineColor );
193 aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth );
194 aDrawer->GetDouble ( MeshVS_DA_BeamWidth, aLineWidth );
195 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, anEdgeOn );
196 aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect );
197 aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
198 aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, toSupressBackFaces);
200 if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt) )
201 anEdgeType = (Aspect_TypeOfLine) anEdgeInt;
203 if ( aDrawer->GetInteger ( MeshVS_DA_BeamType, aLineInt) )
204 aLineType = (Aspect_TypeOfLine) aLineInt;
206 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
207 Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0;
208 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
209 for( ; it.More(); it.Next() )
211 Standard_Integer aKey = it.Key();
212 if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
213 MeshVS_MeshPrsBuilder::HowManyPrimitives
214 ( aTopo, Standard_True, Standard_False, NbNodes,
215 PolygonVerticesFor3D, PolygonBoundsFor3D );
218 Graphic3d_MaterialAspect aMaterial[2];
219 for (Standard_Integer i = 0; i < 2; i++)
221 // OCC20644 "plastic" is most suitable here, as it is "non-physic"
222 // so TelUpdateMaterial() from OpenGl_attri.c uses the interior
223 // color from AspectFillArea3d to calculate all material colors
224 aMaterial[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC );
226 // OCC21720 For single-colored elements turning all material components off is a good idea,
227 // as anyhow the normals are not computed and the lighting will be off,
228 // the element color will be taken from Graphic3d_AspectFillArea3d's interior color,
229 // and there is no need to spend time on updating material properties
232 aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
233 aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
234 aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
235 aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_EMISSION);
239 // OCC20644 This stuff is important in order for elemental and nodal colors
240 // to produce similar visual impression and also to make colors match
241 // those in the color scale most exactly (the sum of all reflection
242 // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder
243 // class for more explanations.
244 aMaterial[i].SetAmbient( .5 );
245 aMaterial[i].SetDiffuse( .5 );
246 aMaterial[i].SetSpecular( 0. );
247 aMaterial[i].SetEmissive( 0. );
251 // Draw elements with one color
252 Handle(Graphic3d_Group) aGGroup, aGroup2, aLGroup, aSGroup;
253 if (!aTwoColorsOfElements.IsEmpty())
255 aGroup2 = Prs3d_Root::NewGroup (Prs);
257 if (!aColorsOfElements.IsEmpty())
259 Handle(Graphic3d_AspectFillArea3d) aGroupFillAspect = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, anInteriorColor, anEdgeColor,
260 anEdgeType, anEdgeWidth, aMaterial[0], aMaterial[1]);
261 aGGroup = Prs3d_Root::NewGroup (Prs);
262 aLGroup = Prs3d_Root::NewGroup (Prs);
263 aGGroup->SetClosed (toSupressBackFaces == Standard_True);
264 aGGroup->SetGroupPrimitivesAspect (aGroupFillAspect);
269 Handle(Graphic3d_AspectLine3d) anEdgeAspect = new Graphic3d_AspectLine3d (anEdgeColor, anEdgeType, anEdgeWidth);
270 aSGroup = Prs3d_Root::NewGroup (Prs);
271 aSGroup->SetGroupPrimitivesAspect (anEdgeAspect);
274 for (MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger aColIter (aColorsOfElements);
275 aColIter.More(); aColIter.Next())
277 if (aColIter.Value().IsEmpty())
282 TColStd_PackedMapOfInteger aCustomElements;
284 Standard_Integer aNbFacePrimitives = 0;
285 Standard_Integer aNbVolmPrimitives = 0;
286 Standard_Integer aNbEdgePrimitives = 0;
287 Standard_Integer aNbLinkPrimitives = 0;
289 for (it.Reset(); it.More(); it.Next())
291 Standard_Integer aNbNodes = 0;
293 if (!aColIter.Value().Contains (it.Key()))
296 if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
299 if (aType == MeshVS_ET_Volume)
301 if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
303 for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
305 const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
307 if (anEdgeOn) // add edge segments
309 aNbEdgePrimitives += aFaceNodes.Length();
312 aNbVolmPrimitives += aFaceNodes.Length() - 2;
316 else if (aType == MeshVS_ET_Link)
320 aNbLinkPrimitives += aNbNodes - 1; // add link segments
323 else if (aType == MeshVS_ET_Face)
327 aNbEdgePrimitives += aNbNodes; // add edge segments
330 aNbFacePrimitives += aNbNodes - 2; // add face triangles
334 // Here we do not use indices arrays because they are not effective for some mesh
335 // drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
336 // cell rendering (normal interpolation is not always applicable - flat shading),
337 // elemental coloring (color interpolation is impossible)
339 Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles (
340 (aNbFacePrimitives + aNbVolmPrimitives) * 3, 0, IsReflect );
341 Standard_Boolean IsPolyG = Standard_False;
343 Handle (Graphic3d_ArrayOfSegments) anEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2);
344 Handle (Graphic3d_ArrayOfSegments) aLinkSegments = new Graphic3d_ArrayOfSegments (aNbLinkPrimitives * 2);
345 Standard_Boolean IsPolyL = Standard_False;
347 // OCC20644 NOTE: aColIter.Key() color is then scaled by TelUpdateMaterial() in OpenGl_attri.c
348 // using the material reflection coefficients. This affects the visual result.
349 Handle(Graphic3d_AspectFillArea3d) aFillAspect =
350 new Graphic3d_AspectFillArea3d ( Aspect_IS_SOLID, aColIter.Key(), anEdgeColor,
351 anEdgeType, anEdgeWidth, aMaterial[0], aMaterial[1] );
353 Handle(Graphic3d_AspectLine3d) aLinkAspect =
354 new Graphic3d_AspectLine3d ( aColIter.Key(), aLineType, aLineWidth );
356 aFillAspect->SetDistinguishOff ();
357 aFillAspect->SetInteriorColor ( aColIter.Key() );
358 aFillAspect->SetEdgeOff();
360 for (it.Reset(); it.More(); it.Next())
362 Standard_Integer aKey = it.Key();
364 if (aColIter.Value().Contains (aKey))
366 if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
369 if (aType != MeshVS_ET_Face && aType != MeshVS_ET_Link && aType != MeshVS_ET_Volume)
371 aCustomElements.Add (aKey);
376 IDsToExclude.Add (aKey);
378 if (aType == MeshVS_ET_Volume)
380 if (!aSource->Get3DGeom (aKey, NbNodes, aTopo))
385 MeshVS_MeshPrsBuilder::AddVolumePrs (aTopo, aCoords,
386 NbNodes, aFaceTriangles, IsReflect, Standard_False, Standard_False, 1.0);
390 MeshVS_MeshPrsBuilder::AddVolumePrs (aTopo, aCoords,
391 NbNodes, anEdgeSegments, IsReflect, Standard_False, Standard_False, 1.0);
394 IsPolyG = Standard_True;
396 else if (aType == MeshVS_ET_Face)
399 Handle(TColStd_HArray1OfReal) aNormals;
400 Standard_Boolean aHasNormals = IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals);
402 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx)
404 for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
408 aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 1),
409 aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 2),
410 aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 3),
411 aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 1) : 0.0,
412 aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 2) : 0.0,
413 aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 3) : 1.0);
417 aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 1),
418 aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 2),
419 aCoords (3 * (anIdx == 0 ? 0 : (aNodeIdx + anIdx)) + 3));
426 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx)
428 const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
430 anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
431 aCoords (3 * aNodeIdx + 2),
432 aCoords (3 * aNodeIdx + 3));
434 anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
435 aCoords (3 * aNextIdx + 2),
436 aCoords (3 * aNextIdx + 3));
440 IsPolyG = Standard_True;
442 else if (aType == MeshVS_ET_Link)
444 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 1; ++aNodeIdx)
446 const Standard_Integer aNextIdx = aNodeIdx + 1;
448 aLinkSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
449 aCoords (3 * aNodeIdx + 2),
450 aCoords (3 * aNodeIdx + 3));
452 aLinkSegments->AddVertex (aCoords (3 * aNextIdx + 1),
453 aCoords (3 * aNextIdx + 2),
454 aCoords (3 * aNextIdx + 3));
456 IsPolyL = Standard_True;
464 aGGroup->SetPrimitivesAspect (aFillAspect);
465 aGGroup->AddPrimitiveArray (aFaceTriangles);
466 aGGroup->SetClosed (toSupressBackFaces == Standard_True);
470 aSGroup->AddPrimitiveArray (anEdgeSegments);
475 aLGroup->SetPrimitivesAspect (aFillAspect);
476 aLGroup->SetPrimitivesAspect (aLinkAspect);
477 aLGroup->AddPrimitiveArray (aLinkSegments);
480 if (!aCustomElements.IsEmpty())
481 CustomBuild(Prs, aCustomElements, IDsToExclude, DisplayMode);
484 Graphic3d_MaterialAspect aMaterial2[2];
485 for (Standard_Integer i = 0; i < 2; i++)
487 // OCC20644 "plastic" is most suitable here, as it is "non-physic"
488 // so TelUpdateMaterial() from OpenGl_attri.c uses the interior
489 // color from AspectFillArea3d to calculate all material colors
490 aMaterial2[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC );
494 // OCC21720 Cannot turn ALL material components off, as such a material
495 // would be ignored by TelUpdateMaterial(), but we need it in order
496 // to have different materials for front and back sides!
497 // Instead, trying to make material color "nondirectional" with
498 // only ambient component on.
499 aMaterial2[i].SetReflectionModeOn ( Graphic3d_TOR_AMBIENT );
500 aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_DIFFUSE );
501 aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_SPECULAR );
502 aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_EMISSION );
503 aMaterial2[i].SetAmbient ( 1. );
504 aMaterial2[i].SetDiffuse ( 0. );
505 aMaterial2[i].SetSpecular( 0. );
506 aMaterial2[i].SetEmissive( 0. );
510 // OCC20644 This stuff is important in order for elemental and nodal colors
511 // to produce similar visual impression and also to make colors match
512 // those in the color scale most exactly (the sum of all reflection
513 // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder
514 // class for more explanations.
515 aMaterial2[i].SetAmbient( .5 );
516 aMaterial2[i].SetDiffuse( .5 );
517 aMaterial2[i].SetSpecular( 0. );
518 aMaterial2[i].SetEmissive( 0. );
522 // Draw faces with two color
523 if (!aTwoColorsOfElements.IsEmpty())
525 Handle(Graphic3d_AspectFillArea3d) aGroupFillAspect2 = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, anInteriorColor, anEdgeColor,
526 anEdgeType, anEdgeWidth, aMaterial2[0], aMaterial2[1]);
527 aGroup2->SetClosed (Standard_False); // ignore toSupressBackFaces
528 aGroup2->SetGroupPrimitivesAspect (aGroupFillAspect2);
530 for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger aColIter2 ( aTwoColorsOfElements );
531 aColIter2.More(); aColIter2.Next() )
533 if (aColIter2.Value().IsEmpty())
538 Standard_Integer aNbFacePrimitives = 0;
539 Standard_Integer aNbEdgePrimitives = 0;
541 for (it.Reset(); it.More(); it.Next())
543 Standard_Integer aNbNodes = 0;
545 if (!aColIter2.Value().Contains (it.Key()))
548 if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
551 if ( aType == MeshVS_ET_Face && aNbNodes > 0 )
555 aNbEdgePrimitives += aNbNodes; // add edge segments
558 aNbFacePrimitives += aNbNodes - 2; // add face triangles
562 Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles
563 (aNbFacePrimitives * 3, 0, IsReflect);
565 Handle (Graphic3d_ArrayOfSegments) anEdgeSegments = new Graphic3d_ArrayOfSegments
566 (aNbEdgePrimitives * 2);
568 MeshVS_TwoColors aTC = aColIter2.Key();
569 Quantity_Color aMyIntColor, aMyBackColor;
570 ExtractColors ( aTC, aMyIntColor, aMyBackColor );
572 // OCC20644 NOTE: aMyIntColor color is then scaled by TelUpdateMaterial() in OpenGl_attri.c
573 // using the material reflection coefficients. This affects the visual result.
574 Handle(Graphic3d_AspectFillArea3d) anAsp =
575 new Graphic3d_AspectFillArea3d ( Aspect_IS_SOLID, aMyIntColor, anEdgeColor,
576 anEdgeType, anEdgeWidth, aMaterial2[0], aMaterial2[1] );
577 anAsp->SetDistinguishOn ();
578 anAsp->SetInteriorColor ( aMyIntColor );
579 anAsp->SetBackInteriorColor ( aMyBackColor );
583 anAsp->SetEdgeOff();*/
584 aGroup2->SetPrimitivesAspect (anAsp);
586 for( it.Reset(); it.More(); it.Next() )
588 Standard_Integer aKey = it.Key();
589 if( aColIter2.Value().Contains( aKey ) )
591 if ( !aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
594 if( IsExcludingOn() )
595 IDsToExclude.Add( aKey );
597 if (aType == MeshVS_ET_Face && NbNodes > 0)
599 // Preparing normal(s) to show reflections if requested
600 Handle(TColStd_HArray1OfReal) aNormals;
601 // OCC21720 Always passing normals to OpenGL to make materials work
602 // For OpenGL: "No normals" -> "No lighting" -> "no materials taken into account"
603 Standard_Boolean aHasNormals = /*IsReflect &&*/
604 aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals);
606 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx)
608 for (Standard_Integer anIdx = 0; anIdx < 3; ++anIdx)
612 aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 1),
613 aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 2),
614 aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 3),
615 aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 1) : 0.0,
616 aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 2) : 0.0,
617 aHasNormals ? aNormals->Value (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 3) : 1.0);
621 aFaceTriangles->AddVertex (aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 1),
622 aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 2),
623 aCoords (3 * (anIdx == 0 ? 0 : aNodeIdx + anIdx) + 3));
630 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx)
632 const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
634 anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
635 aCoords (3 * aNodeIdx + 2),
636 aCoords (3 * aNodeIdx + 3));
638 anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
639 aCoords (3 * aNextIdx + 2),
640 aCoords (3 * aNextIdx + 3));
647 aGroup2->AddPrimitiveArray (aFaceTriangles);
648 aSGroup->AddPrimitiveArray (anEdgeSegments);
652 //================================================================
653 // Function : SetColors
655 //================================================================
656 void MeshVS_ElementalColorPrsBuilder::SetColors1 ( const MeshVS_DataMapOfIntegerColor& theColorMap )
658 myElemColorMap1 = theColorMap;
661 //================================================================
662 // Function : GetColors
664 //================================================================
665 const MeshVS_DataMapOfIntegerColor& MeshVS_ElementalColorPrsBuilder::GetColors1 () const
667 return myElemColorMap1;
670 //================================================================
671 // Function : HasColors1
673 //================================================================
674 Standard_Boolean MeshVS_ElementalColorPrsBuilder::HasColors1 () const
676 return ( myElemColorMap1.Extent() >0 );
679 //================================================================
680 // Function : GetColor1
682 //================================================================
683 Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor1 ( const Standard_Integer ID,
684 Quantity_Color& theColor ) const
686 Standard_Boolean aRes = myElemColorMap1.IsBound ( ID );
688 theColor = myElemColorMap1.Find ( ID );
693 //================================================================
694 // Function : SetColor1
696 //================================================================
697 void MeshVS_ElementalColorPrsBuilder::SetColor1 ( const Standard_Integer theID,
698 const Quantity_Color& theCol )
700 Standard_Boolean aRes = myElemColorMap1.IsBound ( theID );
702 myElemColorMap1.ChangeFind ( theID ) = theCol;
704 myElemColorMap1.Bind ( theID, theCol );
707 //================================================================
708 // Function : SetColors2
710 //================================================================
711 void MeshVS_ElementalColorPrsBuilder::SetColors2 ( const MeshVS_DataMapOfIntegerTwoColors& theColorMap )
713 myElemColorMap2 = theColorMap;
716 //================================================================
717 // Function : GetColors2
719 //================================================================
720 const MeshVS_DataMapOfIntegerTwoColors& MeshVS_ElementalColorPrsBuilder::GetColors2 () const
722 return myElemColorMap2;
725 //================================================================
726 // Function : HasColors2
728 //================================================================
729 Standard_Boolean MeshVS_ElementalColorPrsBuilder::HasColors2 () const
731 return (myElemColorMap2.Extent()>0);
734 //================================================================
735 // Function : GetColor2
737 //================================================================
738 Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor2 ( const Standard_Integer ID,
739 MeshVS_TwoColors& theColor ) const
741 Standard_Boolean aRes = myElemColorMap2.IsBound ( ID );
743 theColor = myElemColorMap2.Find ( ID );
748 //================================================================
749 // Function : GetColor2
751 //================================================================
752 Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor2 ( const Standard_Integer ID,
753 Quantity_Color& theColor1,
754 Quantity_Color& theColor2 ) const
756 MeshVS_TwoColors aTC;
757 Standard_Boolean aRes = GetColor2 ( ID, aTC );
759 ExtractColors ( aTC, theColor1, theColor2 );
763 //================================================================
764 // Function : SetColor2
766 //================================================================
767 void MeshVS_ElementalColorPrsBuilder::SetColor2 ( const Standard_Integer theID,
768 const Quantity_Color& theCol1,
769 const Quantity_Color& theCol2 )
771 SetColor2 ( theID, BindTwoColors ( theCol1, theCol2 ) );
774 //================================================================
775 // Function : SetColor2
777 //================================================================
778 void MeshVS_ElementalColorPrsBuilder::SetColor2 ( const Standard_Integer theID,
779 const MeshVS_TwoColors& theCol )
781 Standard_Boolean aRes = myElemColorMap2.IsBound ( theID );
783 myElemColorMap2.ChangeFind ( theID ) = theCol;
785 myElemColorMap2.Bind ( theID, theCol );