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.
18 // if define _POLYGONES_ ColorPrsBuilder use ArrayOfPolygons for drawing faces
20 #include <Aspect_SequenceOfColor.hxx>
22 #include <Graphic3d_ArrayOfPolygons.hxx>
23 #include <Graphic3d_ArrayOfPolylines.hxx>
24 #include <Graphic3d_ArrayOfPrimitives.hxx>
25 #include <Graphic3d_ArrayOfSegments.hxx>
26 #include <Graphic3d_ArrayOfTriangles.hxx>
27 #include <Graphic3d_AspectFillArea3d.hxx>
28 #include <Graphic3d_AspectLine3d.hxx>
29 #include <Graphic3d_Group.hxx>
30 #include <Graphic3d_Texture2D.hxx>
31 #include <Graphic3d_TextureParams.hxx>
32 #include <Graphic3d_TypeOfTextureMode.hxx>
33 #include <Image_PixMap.hxx>
34 #include <MeshVS_Buffer.hxx>
35 #include <MeshVS_DataSource.hxx>
36 #include <MeshVS_DisplayModeFlags.hxx>
37 #include <MeshVS_Drawer.hxx>
38 #include <MeshVS_DrawerAttribute.hxx>
39 #include <MeshVS_HArray1OfSequenceOfInteger.hxx>
40 #include <MeshVS_Mesh.hxx>
41 #include <MeshVS_MeshPrsBuilder.hxx>
42 #include <MeshVS_NodalColorPrsBuilder.hxx>
43 #include <MeshVS_SymmetricPairHasher.hxx>
44 #include <MeshVS_Tool.hxx>
45 #include <NCollection_Map.hxx>
46 #include <NCollection_Vector.hxx>
47 #include <Prs3d_Drawer.hxx>
48 #include <Prs3d_LineAspect.hxx>
49 #include <Prs3d_Presentation.hxx>
50 #include <Prs3d_Root.hxx>
51 #include <Prs3d_ShadingAspect.hxx>
52 #include <PrsMgr_PresentationManager3d.hxx>
53 #include <Quantity_Array1OfColor.hxx>
54 #include <Quantity_Color.hxx>
55 #include <Standard_Type.hxx>
56 #include <TColStd_Array1OfInteger.hxx>
57 #include <TColStd_Array1OfReal.hxx>
58 #include <TColStd_HArray1OfReal.hxx>
59 #include <TColStd_HPackedMapOfInteger.hxx>
60 #include <TColStd_ListIteratorOfListOfInteger.hxx>
61 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
62 #include <TColStd_SequenceOfInteger.hxx>
64 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_NodalColorPrsBuilder,MeshVS_PrsBuilder)
67 Class : MeshVS_ImageTexture2D
68 Description : Texture for nodal presentation
70 class MeshVS_ImageTexture2D : public Graphic3d_Texture2D
74 MeshVS_ImageTexture2D (const Handle(Image_PixMap)& theImg) : Graphic3d_Texture2D (theImg, Graphic3d_TOT_2D)
76 myParams->SetModulate (Standard_True);
77 myParams->SetFilter (Graphic3d_TOTF_BILINEAR);
82 DEFINE_STANDARD_RTTI_INLINE(MeshVS_ImageTexture2D,Graphic3d_Texture2D)
85 DEFINE_STANDARD_HANDLE (MeshVS_ImageTexture2D, Graphic3d_Texture2D)
88 //================================================================
89 // Function : getNearestPow2
90 // Purpose : Returns the nearest power of two greater than the
92 //================================================================
93 static inline Standard_Integer getNearestPow2( Standard_Integer theValue )
95 // Precaution against overflow
96 Standard_Integer aHalfMax = IntegerLast() >> 1, aRes = 1;
97 if ( theValue > aHalfMax ) theValue = aHalfMax;
98 while ( aRes < theValue ) aRes <<= 1;
103 Class : MeshVS_NodalColorPrsBuilder
104 Description : This class provides methods to create presentation of
105 nodes with assigned color (See hxx for more description )
108 //================================================================
109 // Function : Constructor MeshVS_NodalColorPrsBuilder
111 //================================================================
112 MeshVS_NodalColorPrsBuilder::MeshVS_NodalColorPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
113 const MeshVS_DisplayModeFlags& Flags,
114 const Handle (MeshVS_DataSource)& DS,
115 const Standard_Integer Id,
116 const MeshVS_BuilderPriority& Priority )
117 : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ),
118 myUseTexture( Standard_False ),
119 myInvalidColor( Quantity_NOC_GRAY )
121 SetExcluding ( Standard_True );
124 //================================================================
127 //================================================================
128 void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
129 const TColStd_PackedMapOfInteger& IDs,
130 TColStd_PackedMapOfInteger& IDsToExclude,
131 const Standard_Boolean IsElement,
132 const Standard_Integer DisplayMode) const
134 Handle (MeshVS_DataSource) aSource = GetDataSource();
135 Handle (MeshVS_Drawer) aDrawer = GetDrawer();
136 if ( aSource.IsNull() || aDrawer.IsNull() )
139 Standard_Integer aMaxFaceNodes;
140 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) || aMaxFaceNodes <= 0 )
143 MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
144 TColStd_Array1OfReal aCoords ( aCoordsBuf, 1, 3 * aMaxFaceNodes );
145 Standard_Integer NbNodes;
146 MeshVS_EntityType aType;
148 if ( !( DisplayMode & GetFlags() ) || !IsElement )
151 if ( (myUseTexture && ( !myTextureCoords.Extent() || !myTextureColorMap.Length() )) ||
152 (!myUseTexture && !myNodeColorMap.Extent()) )
155 // subtract the hidden elements and ids to exclude (to minimize allocated memory)
156 TColStd_PackedMapOfInteger anIDs;
158 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
159 if ( !aHiddenElems.IsNull() )
160 anIDs.Subtract( aHiddenElems->Map() );
161 anIDs.Subtract( IDsToExclude );
163 Standard_Boolean IsReflect = Standard_False, IsMeshSmoothShading = Standard_False;
164 aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect );
165 aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
167 // Following parameter are used for texture presentation only
168 int nbColors = 0; // Number of colors from color map
169 int nbTextureColors = 0; // Number of colors in texture (it will be pow of 2)
172 nbColors = myTextureColorMap.Length();
173 nbTextureColors = getNearestPow2( nbColors );
176 Standard_Integer aSize = anIDs.Extent();
178 // Calculate maximum possible number of vertices and bounds
179 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
180 Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0;
181 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
182 for( ; it.More(); it.Next() )
184 Standard_Integer aKey = it.Key();
185 if ( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
186 MeshVS_MeshPrsBuilder::HowManyPrimitives
187 ( aTopo, Standard_True, Standard_False, NbNodes,
188 PolygonVerticesFor3D, PolygonBoundsFor3D );
191 // Draw faces with nodal color
192 // OCC20644 Use "plastic" material as it is "non-physic" and so it is easier to get the required colors
193 Graphic3d_MaterialAspect aMaterial[2] = { Graphic3d_NOM_PLASTIC, Graphic3d_NOM_PLASTIC };
194 for (Standard_Integer i = 0; i < 2; ++i)
196 aMaterial[i].SetSpecularColor (Quantity_NOC_BLACK);
197 aMaterial[i].SetEmissiveColor (Quantity_NOC_BLACK);
200 aMaterial[i].SetAmbientColor (Quantity_NOC_BLACK);
201 aMaterial[i].SetDiffuseColor (Quantity_NOC_BLACK);
204 // OCC20644 Using the material with reflection properties same as in
205 // ElementalColorPrsBuilder, to get the same colors.
206 // Additionally, ambient and diffuse coefficients are used below to scale incoming colors,
207 // to simulate TelUpdateMaterial() function from OpenGl_attri.c.
208 // This is mandatory, as these "scaled" colors are then passed directly to OpenGL
209 // as ambient and diffuse colors of the current material using glColorMaterial().
210 // In ElementalColorPrsBuilder we do not need to do scale the colors, as this
211 // is done by TelUpdateMaterial().
212 // 0.5 is used to have the colors in 3D maximally similar to those in the color scale.
213 // This is possible when the sum of all coefficient is equal to 1.
214 aMaterial[i].SetAmbientColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
215 aMaterial[i].SetDiffuseColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
219 // Create array of polygons for interior presentation of faces and volumes
220 Handle(Graphic3d_ArrayOfPolygons) aCPolyArr = new Graphic3d_ArrayOfPolygons
221 ( aMaxFaceNodes * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D,
222 0, myUseTexture || IsReflect, !myUseTexture, Standard_False, myUseTexture );
224 Standard_Integer aNbFacePrimitives = 0;
225 Standard_Integer aNbVolmPrimitives = 0;
226 Standard_Integer aNbEdgePrimitives = 0;
227 Standard_Integer aNbLinkPrimitives = 0;
229 for (it.Reset(); it.More(); it.Next())
231 Standard_Integer aNbNodes = 0;
233 if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
236 if (aType == MeshVS_ET_Volume)
238 if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
240 for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
242 const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
244 aNbEdgePrimitives += aFaceNodes.Length(); // add edge segments
245 aNbVolmPrimitives += aFaceNodes.Length() - 2; // add volumetric cell triangles
249 else if (aType == MeshVS_ET_Link)
251 aNbLinkPrimitives += aNbNodes - 1; // add link segments
253 else if (aType == MeshVS_ET_Face)
255 aNbEdgePrimitives += aNbNodes; // add edge segments
256 aNbFacePrimitives += aNbNodes - 2; // add face triangles
260 // Here we do not use indices arrays because they are not effective for some mesh
261 // drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
262 // cell rendering (normal interpolation is not always applicable - flat shading),
263 // elemental coloring (color interpolation is impossible)
265 // Create array of polygons for interior presentation of faces and volumes
266 Handle(Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles
267 ( (aNbFacePrimitives + aNbVolmPrimitives) * 3, 0, myUseTexture || IsReflect, !myUseTexture, myUseTexture );
269 // Create array of polylines for presentation of edges
270 Handle(Graphic3d_ArrayOfSegments) anEdgeSegments = new Graphic3d_ArrayOfSegments
271 (aNbEdgePrimitives * 2);
274 Standard_Real aMin = gp::Resolution() * gp::Resolution();
275 gp_Dir aDefNorm( 0., 0., 1. );
277 // Prepare for scaling the incoming colors
278 const Standard_Real anColorRatio = !IsReflect ? 0.44f : 0.5f;
280 for (it.Reset(); it.More(); it.Next())
282 Standard_Integer aKey = it.Key();
284 if (aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
286 TColStd_Array1OfInteger aNodes (1, NbNodes);
288 if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
291 Quantity_Color aNColor;
293 Standard_Boolean isValid = Standard_True;
297 for (Standard_Integer k = 1; k <= NbNodes && isValid; ++k)
298 isValid = myTextureCoords.IsBound (aNodes (k));
302 for (Standard_Integer k = 1; k <= NbNodes && isValid; ++k)
303 isValid = GetColor (aNodes (k), aNColor);
309 // Preparing normal(s) to show reflections if requested
310 Handle(TColStd_HArray1OfReal) aNormals;
312 Standard_Boolean hasNormals =
313 (IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals));
315 if (aType == MeshVS_ET_Face)
317 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx) // triangulate polygon
319 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
321 gp_XYZ aPnt (aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
322 aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
323 aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
325 gp_Vec aNorm = aDefNorm;
329 gp_Vec aTestNorm (aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
330 aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
331 aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
333 if (aTestNorm.SquareMagnitude() > aMin)
335 aNorm = gp_Dir (aTestNorm);
341 const Standard_Real aTexCoord = myTextureCoords (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)));
343 // Transform texture coordinate in accordance with number of colors specified
344 // by upper level and real size of OpenGL texture. The OpenGL texture has border
345 // colors interpolated with the colors from the color map, thats why we need to
346 // shrink texture coordinates around the middle point to exclude areas where the
347 // map colors are interpolated with the borders color
348 aFaceTriangles->AddVertex (aPnt, aNorm, gp_Pnt2d (
349 (aTexCoord * (nbColors - 1.0) + 0.5) / nbTextureColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
353 GetColor (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)), aNColor);
357 aNColor.SetValues (anColorRatio * aNColor.Red(),
358 anColorRatio * aNColor.Green(),
359 anColorRatio * aNColor.Blue(),
362 aFaceTriangles->AddVertex (aPnt, aNorm, aNColor);
366 aFaceTriangles->AddVertex (aPnt, aNColor);
372 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx) // border segmentation
374 const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
376 anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
377 aCoords (3 * aNodeIdx + 2),
378 aCoords (3 * aNodeIdx + 3));
380 anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
381 aCoords (3 * aNextIdx + 2),
382 aCoords (3 * aNextIdx + 3));
385 // if IsExcludingOn then presentation must not be built by other builders
388 IDsToExclude.Add (aKey);
391 else if (aType == MeshVS_ET_Volume)
393 if (!aSource->Get3DGeom (aKey, NbNodes, aTopo))
396 AddVolumePrs (aTopo, aNodes, aCoords, aFaceTriangles,
397 IsReflect, nbColors, nbTextureColors, anColorRatio);
399 AddVolumePrs (aTopo, aNodes, aCoords, anEdgeSegments,
400 IsReflect, nbColors, nbTextureColors, anColorRatio);
402 // if IsExcludingOn then presentation must not be built by other builders
404 IDsToExclude.Add (aKey);
409 Handle(Graphic3d_AspectFillArea3d) anAsp;
411 // Aspect_InteriorStyle aStyle;
412 // Standard_Integer aStyleInt;
413 Aspect_TypeOfLine anEdgeType = Aspect_TOL_SOLID;
414 Standard_Real anEdgeWidth = 1.0;
415 Quantity_Color anInteriorColor;
416 Quantity_Color anEdgeColor, aLineColor;
417 Standard_Boolean aShowEdges = Standard_True;
419 aDrawer->GetColor ( MeshVS_DA_InteriorColor, anInteriorColor );
420 aDrawer->GetColor ( MeshVS_DA_EdgeColor, anEdgeColor );
421 aDrawer->GetColor ( MeshVS_DA_BeamColor, aLineColor );
422 aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth );
423 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, aShowEdges );
425 Standard_Integer anEdgeInt = Aspect_TOL_SOLID;
426 if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt ) )
427 anEdgeType = (Aspect_TypeOfLine) anEdgeInt;
431 Handle(Prs3d_Drawer) aPrsDrawer = myParentMesh->Attributes();
432 if ( aPrsDrawer.IsNull() )
435 aPrsDrawer->SetShadingAspect( new Prs3d_ShadingAspect() );
436 anAsp = aPrsDrawer->ShadingAspect()->Aspect();
437 if ( anAsp.IsNull() )
440 anAsp->SetFrontMaterial( aMaterial[ 0 ] );
441 anAsp->SetBackMaterial( aMaterial[ 1 ] );
444 Handle(Graphic3d_Texture2D) aTexture = CreateTexture();
445 if ( aTexture.IsNull() )
448 anAsp->SetTextureMapOn();
449 anAsp->SetTextureMap( aTexture );
450 anAsp->SetInteriorColor( Quantity_NOC_WHITE );
454 // if ( aDrawer->GetInteger ( MeshVS_DA_InteriorStyle, aStyleInt ) )
455 // aStyle = (Aspect_InteriorStyle)aStyleInt;
457 anAsp = new Graphic3d_AspectFillArea3d (
458 Aspect_IS_SOLID, Quantity_NOC_GRAY, anEdgeColor,
459 anEdgeType, anEdgeWidth, aMaterial[ 0 ], aMaterial[ 1 ] );
462 anAsp->SetDistinguishOff();
465 Handle(Graphic3d_AspectLine3d) anLAsp =
466 new Graphic3d_AspectLine3d( anEdgeColor, anEdgeType, anEdgeWidth );
468 Handle(Graphic3d_Group) aGroup1 = Prs3d_Root::NewGroup (Prs);
470 Standard_Boolean toSupressBackFaces = Standard_False;
471 aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, toSupressBackFaces);
472 aGroup1->SetClosed (toSupressBackFaces == Standard_True);
474 aGroup1->SetPrimitivesAspect( anAsp );
475 aGroup1->AddPrimitiveArray( aFaceTriangles /*aCPolyArr*/ );
476 //aGroup1->AddPrimitiveArray( aCPolyArr );
480 Prs3d_Root::NewGroup ( Prs );
481 Handle(Graphic3d_Group) aGroup2 = Prs3d_Root::CurrentGroup ( Prs );
483 Handle(Graphic3d_AspectFillArea3d) anAspCopy = new Graphic3d_AspectFillArea3d (*anAsp);
484 anAspCopy->SetTextureMapOff();
485 aGroup2->SetPrimitivesAspect( anAspCopy );
486 aGroup2->SetPrimitivesAspect( anLAsp );
487 aGroup2->AddPrimitiveArray( anEdgeSegments );
491 //================================================================
492 // Function : AddVolumePrs
494 //================================================================
495 void MeshVS_NodalColorPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo,
496 const TColStd_Array1OfInteger& theNodes,
497 const TColStd_Array1OfReal& theCoords,
498 const Handle(Graphic3d_ArrayOfPrimitives)& theArray,
499 const Standard_Boolean theIsShaded,
500 const Standard_Integer theNbColors,
501 const Standard_Integer theNbTexColors,
502 const Standard_Real theColorRatio) const
504 Standard_Integer aLow = theCoords.Lower();
506 if (theTopo.IsNull() || theArray.IsNull())
509 Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
513 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
515 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
517 TColStd_Array1OfReal aPolyNodes (0, 3 * aFaceNodes.Length());
519 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length(); ++aNodeIdx)
521 Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1);
523 Standard_Real aX = theCoords.Value (aLow + 3 * anIdx + 0);
524 Standard_Real aY = theCoords.Value (aLow + 3 * anIdx + 1);
525 Standard_Real aZ = theCoords.Value (aLow + 3 * anIdx + 2);
527 aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
528 aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
529 aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
532 gp_Vec aNorm (0.0, 0.0, 1.0);
536 aPolyNodes.SetValue (0, aFaceNodes.Length());
538 if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
540 aNorm.SetCoord (0.0, 0.0, 1.0);
544 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length() - 2; ++aNodeIdx) // triangulate polygon
546 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
548 gp_Pnt aPnt (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
549 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
550 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
554 const Standard_Real aTexCoord = myTextureCoords (theNodes (aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1));
556 theArray->AddVertex (aPnt, aNorm, gp_Pnt2d (
557 (aTexCoord * (theNbColors - 1.0) + 0.5) / theNbTexColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
561 Quantity_Color aNColor;
562 GetColor (theNodes ((aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1)), aNColor);
566 aNColor.SetValues (theColorRatio * aNColor.Red(),
567 theColorRatio * aNColor.Green(),
568 theColorRatio * aNColor.Blue(),
571 theArray->AddVertex (aPnt, aNorm, aNColor);
575 theArray->AddVertex (aPnt, aNColor);
584 // Find all pairs of nodes (edges) to draw (will be drawn only once)
585 NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap;
587 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
589 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
591 for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
593 const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
595 aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1),
596 aFaceNodes.Value (aNextIdx + 1)));
601 for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next())
603 const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
604 const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
606 Standard_Real aX[] = { theCoords.Value (anIdx1 + 0), theCoords.Value (anIdx2 + 0) };
607 Standard_Real aY[] = { theCoords.Value (anIdx1 + 1), theCoords.Value (anIdx2 + 1) };
608 Standard_Real aZ[] = { theCoords.Value (anIdx1 + 2), theCoords.Value (anIdx2 + 2) };
610 theArray->AddVertex (aX[0], aY[0], aZ[0]);
611 theArray->AddVertex (aX[1], aY[1], aZ[1]);
616 //================================================================
617 // Function : SetColors
619 //================================================================
620 void MeshVS_NodalColorPrsBuilder::SetColors (
621 const MeshVS_DataMapOfIntegerColor& theColorMap )
623 myNodeColorMap = theColorMap;
626 //================================================================
627 // Function : GetColors
629 //================================================================
630 const MeshVS_DataMapOfIntegerColor& MeshVS_NodalColorPrsBuilder::GetColors() const
632 return myNodeColorMap;
635 //================================================================
636 // Function : HasColors
638 //================================================================
639 Standard_Boolean MeshVS_NodalColorPrsBuilder::HasColors () const
641 return ( myNodeColorMap.Extent() >0 );
644 //================================================================
645 // Function : GetColor
647 //================================================================
648 Standard_Boolean MeshVS_NodalColorPrsBuilder::GetColor ( const Standard_Integer ID,
649 Quantity_Color& theColor ) const
651 Standard_Boolean aRes = myNodeColorMap.IsBound ( ID );
653 theColor = myNodeColorMap.Find ( ID );
657 //================================================================
658 // Function : SetColor
660 //================================================================
661 void MeshVS_NodalColorPrsBuilder::SetColor ( const Standard_Integer theID,
662 const Quantity_Color& theCol )
664 Standard_Boolean aRes = myNodeColorMap.IsBound ( theID );
666 myNodeColorMap.ChangeFind ( theID ) = theCol;
668 myNodeColorMap.Bind ( theID, theCol );
671 //================================================================
672 // Function : UseTexture
673 // Purpose : Specify whether texture must be used to build presentation
674 //================================================================
675 void MeshVS_NodalColorPrsBuilder::UseTexture( const Standard_Boolean theToUse )
677 myUseTexture = theToUse;
679 myNodeColorMap.Clear();
681 myTextureColorMap.Clear();
684 //================================================================
685 // Function : IsUseTexture
686 // Purpose : Verify whether texture is used to build presentation
687 //================================================================
688 Standard_Boolean MeshVS_NodalColorPrsBuilder::IsUseTexture() const
693 //================================================================
694 // Function : SetColorMap
695 // Purpose : Set colors to be used for texrture presentation.
696 // Generate texture in accordance with given parameters
697 //================================================================
698 void MeshVS_NodalColorPrsBuilder::SetColorMap( const Aspect_SequenceOfColor& theColors )
700 myTextureColorMap = theColors;
703 //================================================================
704 // Function : GetColorMap
705 // Purpose : Return colors used for texrture presentation
706 //================================================================
707 const Aspect_SequenceOfColor& MeshVS_NodalColorPrsBuilder::GetColorMap() const
709 return myTextureColorMap;
712 //================================================================
713 // Function : SetInvalidColor
714 // Purpose : Set color representing invalid texture coordinate
715 // (laying outside range [0, 1])
716 //================================================================
717 void MeshVS_NodalColorPrsBuilder::SetInvalidColor(
718 const Quantity_Color& theInvalidColor )
720 myInvalidColor = theInvalidColor;
723 //================================================================
724 // Function : GetInvalidColor
725 // Purpose : Return color representing invalid texture coordinate
726 // (laying outside range [0, 1])
727 //================================================================
728 Quantity_Color MeshVS_NodalColorPrsBuilder::GetInvalidColor() const
730 return myInvalidColor;
733 //================================================================
734 // Function : SetTextureCoords
735 // Purpose : Specify correspondence between node IDs and texture
736 // coordinates (range [0, 1])
737 //================================================================
738 void MeshVS_NodalColorPrsBuilder::SetTextureCoords (
739 const TColStd_DataMapOfIntegerReal& theMap )
741 myTextureCoords = theMap;
744 //================================================================
745 // Function : GetTextureCoords
746 // Purpose : Get correspondence between node IDs and texture
747 // coordinates (range [0, 1])
748 //================================================================
749 const TColStd_DataMapOfIntegerReal& MeshVS_NodalColorPrsBuilder::GetTextureCoords() const
751 return myTextureCoords;
754 //================================================================
755 // Function : SetTextureCoord
756 // Purpose : Specify correspondence between node ID and texture
757 // coordinate (range [0, 1])
758 //================================================================
759 void MeshVS_NodalColorPrsBuilder::SetTextureCoord( const Standard_Integer theID,
760 const Standard_Real theCoord )
762 myTextureCoords.Bind( theID, theCoord );
765 //================================================================
766 // Function : GetTextureCoord
767 // Purpose : Return correspondence between node IDs and texture
768 // coordinate (range [0, 1])
769 //================================================================
770 Standard_Real MeshVS_NodalColorPrsBuilder::GetTextureCoord( const Standard_Integer theID )
772 return myTextureCoords.IsBound( theID ) ? myTextureCoords( theID ) : -1;
775 //================================================================
776 // Function : CreateTexture
777 // Purpose : Create texture in accordance with myTextureColorMap
778 //================================================================
779 Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const
781 const Standard_Integer aColorsNb = myTextureColorMap.Length();
787 // create and fill image with colors
788 Handle(Image_PixMap) anImage = new Image_PixMap();
789 if (!anImage->InitTrash (Image_Format_RGBA, Standard_Size(getNearestPow2 (aColorsNb)), 2))
794 anImage->SetTopDown (false);
795 for (Standard_Size aCol = 0; aCol < Standard_Size(aColorsNb); ++aCol)
797 const Quantity_Color& aSrcColor = myTextureColorMap.Value (Standard_Integer(aCol) + 1);
798 Image_ColorRGBA& aColor = anImage->ChangeValue<Image_ColorRGBA> (0, aCol);
799 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
800 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
801 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
805 // fill padding bytes
806 const Quantity_Color& aLastColorSrc = myTextureColorMap.Last();
807 const Image_ColorRGBA aLastColor =
809 Standard_Byte(255.0 * aLastColorSrc.Red()),
810 Standard_Byte(255.0 * aLastColorSrc.Green()),
811 Standard_Byte(255.0 * aLastColorSrc.Blue()),
816 for (Standard_Size aCol = (Standard_Size )aColorsNb; aCol < anImage->SizeX(); ++aCol)
818 anImage->ChangeValue<Image_ColorRGBA> (0, aCol) = aLastColor;
821 const Image_ColorRGBA anInvalidColor =
823 Standard_Byte(255.0 * myInvalidColor.Red()),
824 Standard_Byte(255.0 * myInvalidColor.Green()),
825 Standard_Byte(255.0 * myInvalidColor.Blue()),
828 for (Standard_Size aCol = 0; aCol < anImage->SizeX(); ++aCol)
830 anImage->ChangeValue<Image_ColorRGBA> (1, aCol) = anInvalidColor;
834 return new MeshVS_ImageTexture2D (anImage);