0031866: Documentation - add description to Graphic3d_NameOfMaterial enumeration...
[occt.git] / src / MeshVS / MeshVS_NodalColorPrsBuilder.cxx
CommitLineData
b311480e 1// Created on: 2003-11-12
2// Created by: Alexander SOLOVYOV
973c2be1 3// Copyright (c) 2003-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#define _POLYGONES_
7fd59977 17
42cf5bc1 18// if define _POLYGONES_ ColorPrsBuilder use ArrayOfPolygons for drawing faces
7fd59977 19
42cf5bc1 20#include <Aspect_SequenceOfColor.hxx>
21#include <gp_Pnt.hxx>
7fd59977 22#include <Graphic3d_ArrayOfPolygons.hxx>
23#include <Graphic3d_ArrayOfPolylines.hxx>
42cf5bc1 24#include <Graphic3d_ArrayOfPrimitives.hxx>
37ac4a67 25#include <Graphic3d_ArrayOfSegments.hxx>
26#include <Graphic3d_ArrayOfTriangles.hxx>
42cf5bc1 27#include <Graphic3d_AspectFillArea3d.hxx>
28#include <Graphic3d_AspectLine3d.hxx>
7fd59977 29#include <Graphic3d_Group.hxx>
42cf5bc1 30#include <Graphic3d_Texture2D.hxx>
bf75be98 31#include <Graphic3d_TextureParams.hxx>
42cf5bc1 32#include <Graphic3d_TypeOfTextureMode.hxx>
33#include <Image_PixMap.hxx>
34#include <MeshVS_Buffer.hxx>
7fd59977 35#include <MeshVS_DataSource.hxx>
42cf5bc1 36#include <MeshVS_DisplayModeFlags.hxx>
7fd59977 37#include <MeshVS_Drawer.hxx>
42cf5bc1 38#include <MeshVS_DrawerAttribute.hxx>
39#include <MeshVS_HArray1OfSequenceOfInteger.hxx>
7fd59977 40#include <MeshVS_Mesh.hxx>
41#include <MeshVS_MeshPrsBuilder.hxx>
42cf5bc1 42#include <MeshVS_NodalColorPrsBuilder.hxx>
37ac4a67 43#include <MeshVS_SymmetricPairHasher.hxx>
42cf5bc1 44#include <MeshVS_Tool.hxx>
37ac4a67 45#include <NCollection_Map.hxx>
46#include <NCollection_Vector.hxx>
42cf5bc1 47#include <Prs3d_Drawer.hxx>
48#include <Prs3d_LineAspect.hxx>
49#include <Prs3d_Presentation.hxx>
42cf5bc1 50#include <Prs3d_ShadingAspect.hxx>
51#include <PrsMgr_PresentationManager3d.hxx>
52#include <Quantity_Array1OfColor.hxx>
53#include <Quantity_Color.hxx>
54#include <Standard_Type.hxx>
55#include <TColStd_Array1OfInteger.hxx>
56#include <TColStd_Array1OfReal.hxx>
57#include <TColStd_HArray1OfReal.hxx>
58#include <TColStd_HPackedMapOfInteger.hxx>
59#include <TColStd_ListIteratorOfListOfInteger.hxx>
60#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
61#include <TColStd_SequenceOfInteger.hxx>
37ac4a67 62
92efcf78 63IMPLEMENT_STANDARD_RTTIEXT(MeshVS_NodalColorPrsBuilder,MeshVS_PrsBuilder)
64
7fd59977 65/*
66 Class : MeshVS_ImageTexture2D
67 Description : Texture for nodal presentation
68*/
69class MeshVS_ImageTexture2D : public Graphic3d_Texture2D
70{
71public:
bf75be98 72
f376ac72 73 MeshVS_ImageTexture2D (const Handle(Image_PixMap)& theImg) : Graphic3d_Texture2D (theImg, Graphic3d_TOT_2D)
bf75be98 74 {
75 myParams->SetModulate (Standard_True);
76 myParams->SetFilter (Graphic3d_TOTF_BILINEAR);
77 }
78
7fd59977 79public:
bf75be98 80
92efcf78 81 DEFINE_STANDARD_RTTI_INLINE(MeshVS_ImageTexture2D,Graphic3d_Texture2D)
7fd59977 82};
83
3c3131a0 84DEFINE_STANDARD_HANDLE (MeshVS_ImageTexture2D, Graphic3d_Texture2D)
ec357c5c 85
7fd59977 86
7fd59977 87//================================================================
88// Function : getNearestPow2
3c3131a0 89// Purpose : Returns the nearest power of two greater than the
7fd59977 90// argument value
91//================================================================
92static inline Standard_Integer getNearestPow2( Standard_Integer theValue )
93{
94 // Precaution against overflow
95 Standard_Integer aHalfMax = IntegerLast() >> 1, aRes = 1;
96 if ( theValue > aHalfMax ) theValue = aHalfMax;
97 while ( aRes < theValue ) aRes <<= 1;
98 return aRes;
99}
100
101/*
102 Class : MeshVS_NodalColorPrsBuilder
3c3131a0 103 Description : This class provides methods to create presentation of
7fd59977 104 nodes with assigned color (See hxx for more description )
105*/
106
107//================================================================
108// Function : Constructor MeshVS_NodalColorPrsBuilder
109// Purpose :
110//================================================================
111MeshVS_NodalColorPrsBuilder::MeshVS_NodalColorPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
112 const MeshVS_DisplayModeFlags& Flags,
113 const Handle (MeshVS_DataSource)& DS,
114 const Standard_Integer Id,
115 const MeshVS_BuilderPriority& Priority )
116: MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ),
3c3131a0 117 myUseTexture( Standard_False ),
7fd59977 118 myInvalidColor( Quantity_NOC_GRAY )
119{
120 SetExcluding ( Standard_True );
121}
122
123//================================================================
124// Function : Build
125// Purpose :
126//================================================================
127void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
128 const TColStd_PackedMapOfInteger& IDs,
129 TColStd_PackedMapOfInteger& IDsToExclude,
130 const Standard_Boolean IsElement,
131 const Standard_Integer DisplayMode) const
132{
133 Handle (MeshVS_DataSource) aSource = GetDataSource();
134 Handle (MeshVS_Drawer) aDrawer = GetDrawer();
135 if ( aSource.IsNull() || aDrawer.IsNull() )
136 return;
137
138 Standard_Integer aMaxFaceNodes;
139 if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) || aMaxFaceNodes <= 0 )
140 return;
141
142 MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real));
143 TColStd_Array1OfReal aCoords ( aCoordsBuf, 1, 3 * aMaxFaceNodes );
144 Standard_Integer NbNodes;
145 MeshVS_EntityType aType;
146
147 if ( !( DisplayMode & GetFlags() ) || !IsElement )
148 return;
149
0ebaa4db 150 if ( (myUseTexture && ( !myTextureCoords.Extent() || !myTextureColorMap.Length() )) ||
151 (!myUseTexture && !myNodeColorMap.Extent()) )
7fd59977 152 return;
153
37ac4a67 154 // subtract the hidden elements and ids to exclude (to minimize allocated memory)
7fd59977 155 TColStd_PackedMapOfInteger anIDs;
156 anIDs.Assign( IDs );
157 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
158 if ( !aHiddenElems.IsNull() )
159 anIDs.Subtract( aHiddenElems->Map() );
160 anIDs.Subtract( IDsToExclude );
161
162 Standard_Boolean IsReflect = Standard_False, IsMeshSmoothShading = Standard_False;
163 aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect );
164 aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
3c3131a0 165
7fd59977 166 // Following parameter are used for texture presentation only
167 int nbColors = 0; // Number of colors from color map
168 int nbTextureColors = 0; // Number of colors in texture (it will be pow of 2)
169 if ( myUseTexture )
170 {
171 nbColors = myTextureColorMap.Length();
172 nbTextureColors = getNearestPow2( nbColors );
173 }
3c3131a0 174
7fd59977 175 Standard_Integer aSize = anIDs.Extent();
176
177 // Calculate maximum possible number of vertices and bounds
178 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
179 Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0;
180 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
181 for( ; it.More(); it.Next() )
182 {
183 Standard_Integer aKey = it.Key();
184 if ( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
185 MeshVS_MeshPrsBuilder::HowManyPrimitives
186 ( aTopo, Standard_True, Standard_False, NbNodes,
187 PolygonVerticesFor3D, PolygonBoundsFor3D );
188 }
189
190 // Draw faces with nodal color
61168418 191 // OCC20644 Use "plastic" material as it is "non-physic" and so it is easier to get the required colors
a966542b 192 Graphic3d_MaterialAspect aMaterial[2] = { Graphic3d_NameOfMaterial_Plastified, Graphic3d_NameOfMaterial_Plastified };
61168418 193 for (Standard_Integer i = 0; i < 2; ++i)
7fd59977 194 {
61168418 195 aMaterial[i].SetSpecularColor (Quantity_NOC_BLACK);
196 aMaterial[i].SetEmissiveColor (Quantity_NOC_BLACK);
7fd59977 197 if ( !IsReflect )
198 {
61168418 199 aMaterial[i].SetAmbientColor (Quantity_NOC_BLACK);
200 aMaterial[i].SetDiffuseColor (Quantity_NOC_BLACK);
7fd59977 201 }
202 else{
203 // OCC20644 Using the material with reflection properties same as in
204 // ElementalColorPrsBuilder, to get the same colors.
205 // Additionally, ambient and diffuse coefficients are used below to scale incoming colors,
206 // to simulate TelUpdateMaterial() function from OpenGl_attri.c.
207 // This is mandatory, as these "scaled" colors are then passed directly to OpenGL
208 // as ambient and diffuse colors of the current material using glColorMaterial().
209 // In ElementalColorPrsBuilder we do not need to do scale the colors, as this
210 // is done by TelUpdateMaterial().
211 // 0.5 is used to have the colors in 3D maximally similar to those in the color scale.
212 // This is possible when the sum of all coefficient is equal to 1.
61168418 213 aMaterial[i].SetAmbientColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
214 aMaterial[i].SetDiffuseColor (Quantity_Color (Graphic3d_Vec3 (0.5f)));
7fd59977 215 }
61168418 216 }
7fd59977 217
218 // Create array of polygons for interior presentation of faces and volumes
219 Handle(Graphic3d_ArrayOfPolygons) aCPolyArr = new Graphic3d_ArrayOfPolygons
3c3131a0 220 ( aMaxFaceNodes * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D,
7fd59977 221 0, myUseTexture || IsReflect, !myUseTexture, Standard_False, myUseTexture );
222
37ac4a67 223 Standard_Integer aNbFacePrimitives = 0;
224 Standard_Integer aNbVolmPrimitives = 0;
225 Standard_Integer aNbEdgePrimitives = 0;
226 Standard_Integer aNbLinkPrimitives = 0;
227
228 for (it.Reset(); it.More(); it.Next())
229 {
230 Standard_Integer aNbNodes = 0;
231
232 if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
233 continue;
234
235 if (aType == MeshVS_ET_Volume)
236 {
237 if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
238 {
239 for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
240 {
241 const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
242
243 aNbEdgePrimitives += aFaceNodes.Length(); // add edge segments
244 aNbVolmPrimitives += aFaceNodes.Length() - 2; // add volumetric cell triangles
245 }
246 }
247 }
248 else if (aType == MeshVS_ET_Link)
249 {
250 aNbLinkPrimitives += aNbNodes - 1; // add link segments
251 }
252 else if (aType == MeshVS_ET_Face)
253 {
254 aNbEdgePrimitives += aNbNodes; // add edge segments
255 aNbFacePrimitives += aNbNodes - 2; // add face triangles
256 }
257 }
258
259 // Here we do not use indices arrays because they are not effective for some mesh
260 // drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
261 // cell rendering (normal interpolation is not always applicable - flat shading),
262 // elemental coloring (color interpolation is impossible)
263
264 // Create array of polygons for interior presentation of faces and volumes
265 Handle(Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles
266 ( (aNbFacePrimitives + aNbVolmPrimitives) * 3, 0, myUseTexture || IsReflect, !myUseTexture, myUseTexture );
267
3c3131a0 268 // Create array of polylines for presentation of edges
37ac4a67 269 Handle(Graphic3d_ArrayOfSegments) anEdgeSegments = new Graphic3d_ArrayOfSegments
270 (aNbEdgePrimitives * 2);
7fd59977 271
272 gp_Pnt P, Start;
273 Standard_Real aMin = gp::Resolution() * gp::Resolution();
274 gp_Dir aDefNorm( 0., 0., 1. );
275
276 // Prepare for scaling the incoming colors
61168418 277 const Standard_Real anColorRatio = !IsReflect ? 0.44f : 0.5f;
7fd59977 278
37ac4a67 279 for (it.Reset(); it.More(); it.Next())
7fd59977 280 {
281 Standard_Integer aKey = it.Key();
37ac4a67 282
283 if (aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
7fd59977 284 {
37ac4a67 285 TColStd_Array1OfInteger aNodes (1, NbNodes);
286
287 if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
7fd59977 288 continue;
289
290 Quantity_Color aNColor;
291
292 Standard_Boolean isValid = Standard_True;
37ac4a67 293
294 if (myUseTexture)
7fd59977 295 {
51740958 296 for (Standard_Integer k = 1; k <= NbNodes && isValid; ++k)
297 isValid = myTextureCoords.IsBound (aNodes (k));
7fd59977 298 }
299 else
300 {
51740958 301 for (Standard_Integer k = 1; k <= NbNodes && isValid; ++k)
302 isValid = GetColor (aNodes (k), aNColor);
7fd59977 303 }
304
37ac4a67 305 if (!isValid)
7fd59977 306 continue;
307
308 // Preparing normal(s) to show reflections if requested
309 Handle(TColStd_HArray1OfReal) aNormals;
37ac4a67 310
3c3131a0 311 Standard_Boolean hasNormals =
37ac4a67 312 (IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals));
7fd59977 313
37ac4a67 314 if (aType == MeshVS_ET_Face)
7fd59977 315 {
37ac4a67 316 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx) // triangulate polygon
7fd59977 317 {
37ac4a67 318 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
7fd59977 319 {
37ac4a67 320 gp_XYZ aPnt (aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
321 aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
322 aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
7fd59977 323
37ac4a67 324 gp_Vec aNorm = aDefNorm;
7fd59977 325
37ac4a67 326 if (hasNormals)
3ba3388b 327 {
37ac4a67 328 gp_Vec aTestNorm (aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
329 aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
330 aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
3c3131a0 331
37ac4a67 332 if (aTestNorm.SquareMagnitude() > aMin)
7fd59977 333 {
37ac4a67 334 aNorm = gp_Dir (aTestNorm);
7fd59977 335 }
7fd59977 336 }
7fd59977 337
37ac4a67 338 if (myUseTexture)
7fd59977 339 {
37ac4a67 340 const Standard_Real aTexCoord = myTextureCoords (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)));
341
342 // Transform texture coordinate in accordance with number of colors specified
343 // by upper level and real size of OpenGL texture. The OpenGL texture has border
344 // colors interpolated with the colors from the color map, thats why we need to
345 // shrink texture coordinates around the middle point to exclude areas where the
346 // map colors are interpolated with the borders color
347 aFaceTriangles->AddVertex (aPnt, aNorm, gp_Pnt2d (
348 (aTexCoord * (nbColors - 1.0) + 0.5) / nbTextureColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
7fd59977 349 }
350 else
351 {
37ac4a67 352 GetColor (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)), aNColor);
353
354 if (IsReflect)
3c3131a0 355 {
37ac4a67 356 aNColor.SetValues (anColorRatio * aNColor.Red(),
357 anColorRatio * aNColor.Green(),
358 anColorRatio * aNColor.Blue(),
359 Quantity_TOC_RGB);
360
361 aFaceTriangles->AddVertex (aPnt, aNorm, aNColor);
7fd59977 362 }
363 else
37ac4a67 364 {
365 aFaceTriangles->AddVertex (aPnt, aNColor);
366 }
7fd59977 367 }
7fd59977 368 }
37ac4a67 369 }
370
371 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx) // border segmentation
372 {
373 const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
374
375 anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
376 aCoords (3 * aNodeIdx + 2),
377 aCoords (3 * aNodeIdx + 3));
378
379 anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
380 aCoords (3 * aNextIdx + 2),
381 aCoords (3 * aNextIdx + 3));
7fd59977 382 }
383
384 // if IsExcludingOn then presentation must not be built by other builders
37ac4a67 385 if (IsExcludingOn())
386 {
387 IDsToExclude.Add (aKey);
388 }
389 }
390 else if (aType == MeshVS_ET_Volume)
391 {
392 if (!aSource->Get3DGeom (aKey, NbNodes, aTopo))
393 continue;
394
395 AddVolumePrs (aTopo, aNodes, aCoords, aFaceTriangles,
396 IsReflect, nbColors, nbTextureColors, anColorRatio);
397
398 AddVolumePrs (aTopo, aNodes, aCoords, anEdgeSegments,
399 IsReflect, nbColors, nbTextureColors, anColorRatio);
400
401 // if IsExcludingOn then presentation must not be built by other builders
402 if (IsExcludingOn())
403 IDsToExclude.Add (aKey);
3c3131a0 404 }
405 }
7fd59977 406 } // for ( ...
407
408 Handle(Graphic3d_AspectFillArea3d) anAsp;
409
410// Aspect_InteriorStyle aStyle;
411// Standard_Integer aStyleInt;
412 Aspect_TypeOfLine anEdgeType = Aspect_TOL_SOLID;
b1492cb3 413 Standard_Real anEdgeWidth = 1.0;
7fd59977 414 Quantity_Color anInteriorColor;
415 Quantity_Color anEdgeColor, aLineColor;
416 Standard_Boolean aShowEdges = Standard_True;
417
418 aDrawer->GetColor ( MeshVS_DA_InteriorColor, anInteriorColor );
419 aDrawer->GetColor ( MeshVS_DA_EdgeColor, anEdgeColor );
420 aDrawer->GetColor ( MeshVS_DA_BeamColor, aLineColor );
421 aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth );
422 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, aShowEdges );
423
b1492cb3 424 Standard_Integer anEdgeInt = Aspect_TOL_SOLID;
7fd59977 425 if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt ) )
426 anEdgeType = (Aspect_TypeOfLine) anEdgeInt;
427
428 if ( myUseTexture )
429 {
6262338c 430 Handle(Prs3d_Drawer) aPrsDrawer = myParentMesh->Attributes();
431 if ( aPrsDrawer.IsNull() )
7fd59977 432 return;
3c3131a0 433
6262338c 434 aPrsDrawer->SetShadingAspect( new Prs3d_ShadingAspect() );
435 anAsp = aPrsDrawer->ShadingAspect()->Aspect();
7fd59977 436 if ( anAsp.IsNull() )
437 return;
438
439 anAsp->SetFrontMaterial( aMaterial[ 0 ] );
440 anAsp->SetBackMaterial( aMaterial[ 1 ] );
3c3131a0 441
7fd59977 442
443 Handle(Graphic3d_Texture2D) aTexture = CreateTexture();
444 if ( aTexture.IsNull() )
445 return;
446
3c3131a0 447 anAsp->SetTextureMapOn();
7fd59977 448 anAsp->SetTextureMap( aTexture );
3ba3388b 449 anAsp->SetInteriorColor( Quantity_NOC_WHITE );
7fd59977 450 }
451 else
452 {
453// if ( aDrawer->GetInteger ( MeshVS_DA_InteriorStyle, aStyleInt ) )
454// aStyle = (Aspect_InteriorStyle)aStyleInt;
455
3c3131a0 456 anAsp = new Graphic3d_AspectFillArea3d (
7fd59977 457 Aspect_IS_SOLID, Quantity_NOC_GRAY, anEdgeColor,
458 anEdgeType, anEdgeWidth, aMaterial[ 0 ], aMaterial[ 1 ] );
459 }
460
461 anAsp->SetDistinguishOff();
462 anAsp->SetEdgeOff();
7fd59977 463
3c3131a0 464 Handle(Graphic3d_AspectLine3d) anLAsp =
7fd59977 465 new Graphic3d_AspectLine3d( anEdgeColor, anEdgeType, anEdgeWidth );
3c3131a0 466
d6c48921 467 Handle(Graphic3d_Group) aGroup1 = Prs->NewGroup();
cde2e2f0 468
469 Standard_Boolean toSupressBackFaces = Standard_False;
470 aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, toSupressBackFaces);
471 aGroup1->SetClosed (toSupressBackFaces == Standard_True);
3c3131a0 472
7fd59977 473 aGroup1->SetPrimitivesAspect( anAsp );
37ac4a67 474 aGroup1->AddPrimitiveArray( aFaceTriangles /*aCPolyArr*/ );
475 //aGroup1->AddPrimitiveArray( aCPolyArr );
7fd59977 476
477 if (aShowEdges)
478 {
d6c48921 479 Handle(Graphic3d_Group) aGroup2 = Prs->NewGroup();
7fd59977 480
b6472664 481 Handle(Graphic3d_AspectFillArea3d) anAspCopy = new Graphic3d_AspectFillArea3d (*anAsp);
482 anAspCopy->SetTextureMapOff();
483 aGroup2->SetPrimitivesAspect( anAspCopy );
7fd59977 484 aGroup2->SetPrimitivesAspect( anLAsp );
37ac4a67 485 aGroup2->AddPrimitiveArray( anEdgeSegments );
7fd59977 486 }
487}
488
37ac4a67 489//================================================================
490// Function : AddVolumePrs
491// Purpose :
492//================================================================
493void MeshVS_NodalColorPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo,
494 const TColStd_Array1OfInteger& theNodes,
495 const TColStd_Array1OfReal& theCoords,
496 const Handle(Graphic3d_ArrayOfPrimitives)& theArray,
497 const Standard_Boolean theIsShaded,
498 const Standard_Integer theNbColors,
499 const Standard_Integer theNbTexColors,
500 const Standard_Real theColorRatio) const
501{
502 Standard_Integer aLow = theCoords.Lower();
503
504 if (theTopo.IsNull() || theArray.IsNull())
505 return;
506
507 Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
508
509 if (aIsPolygons)
510 {
511 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
512 {
513 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
514
515 TColStd_Array1OfReal aPolyNodes (0, 3 * aFaceNodes.Length());
516
517 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length(); ++aNodeIdx)
518 {
519 Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1);
520
521 Standard_Real aX = theCoords.Value (aLow + 3 * anIdx + 0);
522 Standard_Real aY = theCoords.Value (aLow + 3 * anIdx + 1);
523 Standard_Real aZ = theCoords.Value (aLow + 3 * anIdx + 2);
524
525 aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
526 aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
527 aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
528 }
529
530 gp_Vec aNorm (0.0, 0.0, 1.0);
531
532 if (theIsShaded)
533 {
534 aPolyNodes.SetValue (0, aFaceNodes.Length());
535
536 if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
537 {
538 aNorm.SetCoord (0.0, 0.0, 1.0);
539 }
540 }
541
542 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length() - 2; ++aNodeIdx) // triangulate polygon
543 {
544 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
545 {
546 gp_Pnt aPnt (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
547 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
548 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
549
550 if (myUseTexture)
551 {
552 const Standard_Real aTexCoord = myTextureCoords (theNodes (aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1));
553
554 theArray->AddVertex (aPnt, aNorm, gp_Pnt2d (
555 (aTexCoord * (theNbColors - 1.0) + 0.5) / theNbTexColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
556 }
557 else
558 {
559 Quantity_Color aNColor;
560 GetColor (theNodes ((aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1)), aNColor);
561
562 if (theIsShaded)
563 {
564 aNColor.SetValues (theColorRatio * aNColor.Red(),
565 theColorRatio * aNColor.Green(),
566 theColorRatio * aNColor.Blue(),
567 Quantity_TOC_RGB);
568
569 theArray->AddVertex (aPnt, aNorm, aNColor);
570 }
571 else
572 {
573 theArray->AddVertex (aPnt, aNColor);
574 }
575 }
576 }
577 }
578 }
579 }
580 else
581 {
582 // Find all pairs of nodes (edges) to draw (will be drawn only once)
583 NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap;
584
585 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
586 {
587 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
588
589 for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
590 {
591 const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
592
593 aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1),
594 aFaceNodes.Value (aNextIdx + 1)));
595 }
596 }
597
598 // Draw edges
599 for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next())
600 {
601 const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
602 const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
603
604 Standard_Real aX[] = { theCoords.Value (anIdx1 + 0), theCoords.Value (anIdx2 + 0) };
605 Standard_Real aY[] = { theCoords.Value (anIdx1 + 1), theCoords.Value (anIdx2 + 1) };
606 Standard_Real aZ[] = { theCoords.Value (anIdx1 + 2), theCoords.Value (anIdx2 + 2) };
607
608 theArray->AddVertex (aX[0], aY[0], aZ[0]);
609 theArray->AddVertex (aX[1], aY[1], aZ[1]);
610 }
611 }
612}
613
7fd59977 614//================================================================
615// Function : SetColors
616// Purpose :
617//================================================================
3c3131a0 618void MeshVS_NodalColorPrsBuilder::SetColors (
7fd59977 619 const MeshVS_DataMapOfIntegerColor& theColorMap )
620{
621 myNodeColorMap = theColorMap;
622}
623
624//================================================================
625// Function : GetColors
626// Purpose :
627//================================================================
628const MeshVS_DataMapOfIntegerColor& MeshVS_NodalColorPrsBuilder::GetColors() const
629{
630 return myNodeColorMap;
631}
632
633//================================================================
634// Function : HasColors
635// Purpose :
636//================================================================
637Standard_Boolean MeshVS_NodalColorPrsBuilder::HasColors () const
638{
639 return ( myNodeColorMap.Extent() >0 );
640}
641
642//================================================================
643// Function : GetColor
644// Purpose :
645//================================================================
646Standard_Boolean MeshVS_NodalColorPrsBuilder::GetColor ( const Standard_Integer ID,
647 Quantity_Color& theColor ) const
648{
649 Standard_Boolean aRes = myNodeColorMap.IsBound ( ID );
650 if ( aRes )
651 theColor = myNodeColorMap.Find ( ID );
652 return aRes;
653}
654
655//================================================================
656// Function : SetColor
657// Purpose :
658//================================================================
659void MeshVS_NodalColorPrsBuilder::SetColor ( const Standard_Integer theID,
660 const Quantity_Color& theCol )
661{
662 Standard_Boolean aRes = myNodeColorMap.IsBound ( theID );
663 if ( aRes )
664 myNodeColorMap.ChangeFind ( theID ) = theCol;
665 else
666 myNodeColorMap.Bind ( theID, theCol );
667}
668
669//================================================================
670// Function : UseTexture
671// Purpose : Specify whether texture must be used to build presentation
672//================================================================
673void MeshVS_NodalColorPrsBuilder::UseTexture( const Standard_Boolean theToUse )
674{
675 myUseTexture = theToUse;
676 if ( myUseTexture )
677 myNodeColorMap.Clear();
678 else
679 myTextureColorMap.Clear();
680}
681
682//================================================================
683// Function : IsUseTexture
684// Purpose : Verify whether texture is used to build presentation
685//================================================================
686Standard_Boolean MeshVS_NodalColorPrsBuilder::IsUseTexture() const
687{
688 return myUseTexture;
689}
690
691//================================================================
692// Function : SetColorMap
3c3131a0 693// Purpose : Set colors to be used for texrture presentation.
7fd59977 694// Generate texture in accordance with given parameters
695//================================================================
696void MeshVS_NodalColorPrsBuilder::SetColorMap( const Aspect_SequenceOfColor& theColors )
697{
698 myTextureColorMap = theColors;
699}
700
701//================================================================
702// Function : GetColorMap
3c3131a0 703// Purpose : Return colors used for texrture presentation
7fd59977 704//================================================================
705const Aspect_SequenceOfColor& MeshVS_NodalColorPrsBuilder::GetColorMap() const
706{
707 return myTextureColorMap;
708}
709
710//================================================================
711// Function : SetInvalidColor
3c3131a0 712// Purpose : Set color representing invalid texture coordinate
7fd59977 713// (laying outside range [0, 1])
714//================================================================
3c3131a0 715void MeshVS_NodalColorPrsBuilder::SetInvalidColor(
7fd59977 716 const Quantity_Color& theInvalidColor )
717{
718 myInvalidColor = theInvalidColor;
719}
720
721//================================================================
722// Function : GetInvalidColor
723// Purpose : Return color representing invalid texture coordinate
724// (laying outside range [0, 1])
725//================================================================
726Quantity_Color MeshVS_NodalColorPrsBuilder::GetInvalidColor() const
727{
728 return myInvalidColor;
729}
730
731//================================================================
732// Function : SetTextureCoords
3c3131a0 733// Purpose : Specify correspondence between node IDs and texture
7fd59977 734// coordinates (range [0, 1])
735//================================================================
3c3131a0 736void MeshVS_NodalColorPrsBuilder::SetTextureCoords (
7fd59977 737 const TColStd_DataMapOfIntegerReal& theMap )
738{
739 myTextureCoords = theMap;
740}
741
742//================================================================
743// Function : GetTextureCoords
3c3131a0 744// Purpose : Get correspondence between node IDs and texture
745// coordinates (range [0, 1])
7fd59977 746//================================================================
747const TColStd_DataMapOfIntegerReal& MeshVS_NodalColorPrsBuilder::GetTextureCoords() const
748{
749 return myTextureCoords;
750}
751
752//================================================================
753// Function : SetTextureCoord
3c3131a0 754// Purpose : Specify correspondence between node ID and texture
755// coordinate (range [0, 1])
7fd59977 756//================================================================
757void MeshVS_NodalColorPrsBuilder::SetTextureCoord( const Standard_Integer theID,
758 const Standard_Real theCoord )
759{
760 myTextureCoords.Bind( theID, theCoord );
761}
762
763//================================================================
764// Function : GetTextureCoord
3c3131a0 765// Purpose : Return correspondence between node IDs and texture
766// coordinate (range [0, 1])
7fd59977 767//================================================================
768Standard_Real MeshVS_NodalColorPrsBuilder::GetTextureCoord( const Standard_Integer theID )
769{
770 return myTextureCoords.IsBound( theID ) ? myTextureCoords( theID ) : -1;
771}
772
773//================================================================
774// Function : CreateTexture
775// Purpose : Create texture in accordance with myTextureColorMap
776//================================================================
777Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const
778{
3c3131a0 779 const Standard_Integer aColorsNb = myTextureColorMap.Length();
780 if (aColorsNb == 0)
781 {
782 return NULL;
783 }
7fd59977 784
3c3131a0 785 // create and fill image with colors
bf75be98 786 Handle(Image_PixMap) anImage = new Image_PixMap();
dc858f4c 787 if (!anImage->InitTrash (Image_Format_RGBA, Standard_Size(getNearestPow2 (aColorsNb)), 2))
3c3131a0 788 {
789 return NULL;
790 }
7fd59977 791
bf75be98 792 anImage->SetTopDown (false);
3c3131a0 793 for (Standard_Size aCol = 0; aCol < Standard_Size(aColorsNb); ++aCol)
794 {
795 const Quantity_Color& aSrcColor = myTextureColorMap.Value (Standard_Integer(aCol) + 1);
ca0c0b11 796 Image_ColorRGBA& aColor = anImage->ChangeValue<Image_ColorRGBA> (0, aCol);
8263fcd3 797 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
798 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
799 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
3c3131a0 800 aColor.a() = 0xFF;
801 }
7fd59977 802
3c3131a0 803 // fill padding bytes
804 const Quantity_Color& aLastColorSrc = myTextureColorMap.Last();
805 const Image_ColorRGBA aLastColor =
806 {{
8263fcd3 807 Standard_Byte(255.0 * aLastColorSrc.Red()),
808 Standard_Byte(255.0 * aLastColorSrc.Green()),
809 Standard_Byte(255.0 * aLastColorSrc.Blue()),
3c3131a0 810 0xFF
811 }};
812
813 // fill second row
bf75be98 814 for (Standard_Size aCol = (Standard_Size )aColorsNb; aCol < anImage->SizeX(); ++aCol)
7fd59977 815 {
ca0c0b11 816 anImage->ChangeValue<Image_ColorRGBA> (0, aCol) = aLastColor;
7fd59977 817 }
818
3c3131a0 819 const Image_ColorRGBA anInvalidColor =
820 {{
8263fcd3 821 Standard_Byte(255.0 * myInvalidColor.Red()),
822 Standard_Byte(255.0 * myInvalidColor.Green()),
823 Standard_Byte(255.0 * myInvalidColor.Blue()),
3c3131a0 824 0xFF
825 }};
bf75be98 826 for (Standard_Size aCol = 0; aCol < anImage->SizeX(); ++aCol)
3c3131a0 827 {
ca0c0b11 828 anImage->ChangeValue<Image_ColorRGBA> (1, aCol) = anInvalidColor;
3c3131a0 829 }
7fd59977 830
3c3131a0 831 // create texture
bf75be98 832 return new MeshVS_ImageTexture2D (anImage);
7fd59977 833}