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