0024023: Revamp the OCCT Handle -- ambiguity
[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_
17// if define _POLYGONES_ ColorPrsBuilder use ArrayOfPolygons for drawing faces
18
19#include <MeshVS_NodalColorPrsBuilder.ixx>
20
21#include <Graphic3d_AspectFillArea3d.hxx>
22#include <Graphic3d_AspectLine3d.hxx>
23#include <Graphic3d_ArrayOfPolygons.hxx>
24#include <Graphic3d_ArrayOfPolylines.hxx>
37ac4a67 25#include <Graphic3d_ArrayOfSegments.hxx>
26#include <Graphic3d_ArrayOfTriangles.hxx>
7fd59977 27#include <Graphic3d_Group.hxx>
bf75be98 28#include <Graphic3d_TextureParams.hxx>
7fd59977 29
6262338c 30#include <Prs3d_Drawer.hxx>
7fd59977 31#include <Prs3d_ShadingAspect.hxx>
32#include <Prs3d_Root.hxx>
33#include <Prs3d_LineAspect.hxx>
34
35#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
36#include <TColStd_ListIteratorOfListOfInteger.hxx>
37#include <TColStd_Array1OfReal.hxx>
38#include <TColStd_HArray1OfReal.hxx>
39#include <TColStd_Array1OfInteger.hxx>
40#include <TColStd_SequenceOfInteger.hxx>
41#include <TColStd_HPackedMapOfInteger.hxx>
42
43#include <MeshVS_DisplayModeFlags.hxx>
44#include <MeshVS_DrawerAttribute.hxx>
45#include <MeshVS_DataSource.hxx>
46#include <MeshVS_Drawer.hxx>
47#include <MeshVS_Mesh.hxx>
48#include <MeshVS_MeshPrsBuilder.hxx>
49#include <MeshVS_HArray1OfSequenceOfInteger.hxx>
50#include <MeshVS_Buffer.hxx>
37ac4a67 51#include <MeshVS_Tool.hxx>
52#include <MeshVS_SymmetricPairHasher.hxx>
7fd59977 53
54#include <gp_Pnt.hxx>
3c3131a0 55#include <Image_PixMap.hxx>
7fd59977 56#include <Graphic3d_Texture2D.hxx>
57#include <Graphic3d_TypeOfTextureMode.hxx>
ec357c5c 58#include <Standard_Type.hxx>
7fd59977 59#include <PrsMgr_PresentationManager3d.hxx>
7fd59977 60#include <Quantity_Array1OfColor.hxx>
61#include <Aspect_SequenceOfColor.hxx>
62
37ac4a67 63#include <NCollection_Map.hxx>
64#include <NCollection_Vector.hxx>
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
ec357c5c 82 DEFINE_STANDARD_RTTI(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;
302 Standard_Integer i;
37ac4a67 303
304 if (myUseTexture)
7fd59977 305 {
37ac4a67 306 for (i = 1; i <= NbNodes && isValid; ++i)
307 isValid = myTextureCoords.IsBound (aNodes (i));
7fd59977 308 }
309 else
310 {
37ac4a67 311 for (i = 1; i <= NbNodes && isValid; ++i)
312 isValid = GetColor (aNodes (i), aNColor);
7fd59977 313 }
314
37ac4a67 315 if (!isValid)
7fd59977 316 continue;
317
318 // Preparing normal(s) to show reflections if requested
319 Handle(TColStd_HArray1OfReal) aNormals;
37ac4a67 320
3c3131a0 321 Standard_Boolean hasNormals =
37ac4a67 322 (IsReflect && aSource->GetNormalsByElement (aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals));
7fd59977 323
37ac4a67 324 if (aType == MeshVS_ET_Face)
7fd59977 325 {
37ac4a67 326 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes - 2; ++aNodeIdx) // triangulate polygon
7fd59977 327 {
37ac4a67 328 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
7fd59977 329 {
37ac4a67 330 gp_XYZ aPnt (aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
331 aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
332 aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
7fd59977 333
37ac4a67 334 gp_Vec aNorm = aDefNorm;
7fd59977 335
37ac4a67 336 if (hasNormals)
3ba3388b 337 {
37ac4a67 338 gp_Vec aTestNorm (aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
339 aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
340 aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
3c3131a0 341
37ac4a67 342 if (aTestNorm.SquareMagnitude() > aMin)
7fd59977 343 {
37ac4a67 344 aNorm = gp_Dir (aTestNorm);
7fd59977 345 }
7fd59977 346 }
7fd59977 347
37ac4a67 348 if (myUseTexture)
7fd59977 349 {
37ac4a67 350 const Standard_Real aTexCoord = myTextureCoords (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)));
351
352 // Transform texture coordinate in accordance with number of colors specified
353 // by upper level and real size of OpenGL texture. The OpenGL texture has border
354 // colors interpolated with the colors from the color map, thats why we need to
355 // shrink texture coordinates around the middle point to exclude areas where the
356 // map colors are interpolated with the borders color
357 aFaceTriangles->AddVertex (aPnt, aNorm, gp_Pnt2d (
358 (aTexCoord * (nbColors - 1.0) + 0.5) / nbTextureColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
7fd59977 359 }
360 else
361 {
37ac4a67 362 GetColor (aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)), aNColor);
363
364 if (IsReflect)
3c3131a0 365 {
37ac4a67 366 aNColor.SetValues (anColorRatio * aNColor.Red(),
367 anColorRatio * aNColor.Green(),
368 anColorRatio * aNColor.Blue(),
369 Quantity_TOC_RGB);
370
371 aFaceTriangles->AddVertex (aPnt, aNorm, aNColor);
7fd59977 372 }
373 else
37ac4a67 374 {
375 aFaceTriangles->AddVertex (aPnt, aNColor);
376 }
7fd59977 377 }
7fd59977 378 }
37ac4a67 379 }
380
381 for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes; ++aNodeIdx) // border segmentation
382 {
383 const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
384
385 anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
386 aCoords (3 * aNodeIdx + 2),
387 aCoords (3 * aNodeIdx + 3));
388
389 anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
390 aCoords (3 * aNextIdx + 2),
391 aCoords (3 * aNextIdx + 3));
7fd59977 392 }
393
394 // if IsExcludingOn then presentation must not be built by other builders
37ac4a67 395 if (IsExcludingOn())
396 {
397 IDsToExclude.Add (aKey);
398 }
399 }
400 else if (aType == MeshVS_ET_Volume)
401 {
402 if (!aSource->Get3DGeom (aKey, NbNodes, aTopo))
403 continue;
404
405 AddVolumePrs (aTopo, aNodes, aCoords, aFaceTriangles,
406 IsReflect, nbColors, nbTextureColors, anColorRatio);
407
408 AddVolumePrs (aTopo, aNodes, aCoords, anEdgeSegments,
409 IsReflect, nbColors, nbTextureColors, anColorRatio);
410
411 // if IsExcludingOn then presentation must not be built by other builders
412 if (IsExcludingOn())
413 IDsToExclude.Add (aKey);
3c3131a0 414 }
415 }
7fd59977 416 } // for ( ...
417
418 Handle(Graphic3d_AspectFillArea3d) anAsp;
419
420// Aspect_InteriorStyle aStyle;
421// Standard_Integer aStyleInt;
422 Aspect_TypeOfLine anEdgeType = Aspect_TOL_SOLID;
423 Standard_Integer anEdgeInt;
424 Standard_Real anEdgeWidth;
425 Quantity_Color anInteriorColor;
426 Quantity_Color anEdgeColor, aLineColor;
427 Standard_Boolean aShowEdges = Standard_True;
428
429 aDrawer->GetColor ( MeshVS_DA_InteriorColor, anInteriorColor );
430 aDrawer->GetColor ( MeshVS_DA_EdgeColor, anEdgeColor );
431 aDrawer->GetColor ( MeshVS_DA_BeamColor, aLineColor );
432 aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth );
433 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, aShowEdges );
434
435 if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt ) )
436 anEdgeType = (Aspect_TypeOfLine) anEdgeInt;
437
438 if ( myUseTexture )
439 {
6262338c 440 Handle(Prs3d_Drawer) aPrsDrawer = myParentMesh->Attributes();
441 if ( aPrsDrawer.IsNull() )
7fd59977 442 return;
3c3131a0 443
6262338c 444 aPrsDrawer->SetShadingAspect( new Prs3d_ShadingAspect() );
445 anAsp = aPrsDrawer->ShadingAspect()->Aspect();
7fd59977 446 if ( anAsp.IsNull() )
447 return;
448
449 anAsp->SetFrontMaterial( aMaterial[ 0 ] );
450 anAsp->SetBackMaterial( aMaterial[ 1 ] );
3c3131a0 451
7fd59977 452
453 Handle(Graphic3d_Texture2D) aTexture = CreateTexture();
454 if ( aTexture.IsNull() )
455 return;
456
3c3131a0 457 anAsp->SetTextureMapOn();
7fd59977 458 anAsp->SetTextureMap( aTexture );
3ba3388b 459 anAsp->SetInteriorColor( Quantity_NOC_WHITE );
7fd59977 460 }
461 else
462 {
463// if ( aDrawer->GetInteger ( MeshVS_DA_InteriorStyle, aStyleInt ) )
464// aStyle = (Aspect_InteriorStyle)aStyleInt;
465
3c3131a0 466 anAsp = new Graphic3d_AspectFillArea3d (
7fd59977 467 Aspect_IS_SOLID, Quantity_NOC_GRAY, anEdgeColor,
468 anEdgeType, anEdgeWidth, aMaterial[ 0 ], aMaterial[ 1 ] );
469 }
470
471 anAsp->SetDistinguishOff();
472 anAsp->SetEdgeOff();
7fd59977 473
3c3131a0 474 Handle(Graphic3d_AspectLine3d) anLAsp =
7fd59977 475 new Graphic3d_AspectLine3d( anEdgeColor, anEdgeType, anEdgeWidth );
3c3131a0 476
7fd59977 477 Prs3d_Root::NewGroup ( Prs );
478 Handle(Graphic3d_Group) aGroup1 = Prs3d_Root::CurrentGroup ( Prs );
3c3131a0 479
7fd59977 480 aGroup1->SetPrimitivesAspect( anAsp );
37ac4a67 481 aGroup1->AddPrimitiveArray( aFaceTriangles /*aCPolyArr*/ );
482 //aGroup1->AddPrimitiveArray( aCPolyArr );
7fd59977 483
484 if (aShowEdges)
485 {
486 Prs3d_Root::NewGroup ( Prs );
487 Handle(Graphic3d_Group) aGroup2 = Prs3d_Root::CurrentGroup ( Prs );
488
489 anAsp->SetEdgeOff();
3c3131a0 490 anAsp->SetTextureMapOff();
7fd59977 491 aGroup2->SetPrimitivesAspect( anAsp );
492 aGroup2->SetPrimitivesAspect( anLAsp );
37ac4a67 493 aGroup2->AddPrimitiveArray( anEdgeSegments );
7fd59977 494 anAsp->SetEdgeOn();
495 }
496}
497
498//================================================================
37ac4a67 499// Function : AddVolumePrs
500// Purpose :
501//================================================================
502void MeshVS_NodalColorPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo,
503 const TColStd_Array1OfInteger& theNodes,
504 const TColStd_Array1OfReal& theCoords,
505 const Handle(Graphic3d_ArrayOfPrimitives)& theArray,
506 const Standard_Boolean theIsShaded,
507 const Standard_Integer theNbColors,
508 const Standard_Integer theNbTexColors,
509 const Standard_Real theColorRatio) const
510{
511 Standard_Integer aLow = theCoords.Lower();
512
513 if (theTopo.IsNull() || theArray.IsNull())
514 return;
515
516 Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
517
518 if (aIsPolygons)
519 {
520 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
521 {
522 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
523
524 TColStd_Array1OfReal aPolyNodes (0, 3 * aFaceNodes.Length());
525
526 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length(); ++aNodeIdx)
527 {
528 Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1);
529
530 Standard_Real aX = theCoords.Value (aLow + 3 * anIdx + 0);
531 Standard_Real aY = theCoords.Value (aLow + 3 * anIdx + 1);
532 Standard_Real aZ = theCoords.Value (aLow + 3 * anIdx + 2);
533
534 aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
535 aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
536 aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
537 }
538
539 gp_Vec aNorm (0.0, 0.0, 1.0);
540
541 if (theIsShaded)
542 {
543 aPolyNodes.SetValue (0, aFaceNodes.Length());
544
545 if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
546 {
547 aNorm.SetCoord (0.0, 0.0, 1.0);
548 }
549 }
550
551 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aFaceNodes.Length() - 2; ++aNodeIdx) // triangulate polygon
552 {
553 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
554 {
555 gp_Pnt aPnt (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
556 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
557 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
558
559 if (myUseTexture)
560 {
561 const Standard_Real aTexCoord = myTextureCoords (theNodes (aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1));
562
563 theArray->AddVertex (aPnt, aNorm, gp_Pnt2d (
564 (aTexCoord * (theNbColors - 1.0) + 0.5) / theNbTexColors, aTexCoord < 0 || aTexCoord > 1 ? 0.25 : 0.75));
565 }
566 else
567 {
568 Quantity_Color aNColor;
569 GetColor (theNodes ((aFaceNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1)) + 1)), aNColor);
570
571 if (theIsShaded)
572 {
573 aNColor.SetValues (theColorRatio * aNColor.Red(),
574 theColorRatio * aNColor.Green(),
575 theColorRatio * aNColor.Blue(),
576 Quantity_TOC_RGB);
577
578 theArray->AddVertex (aPnt, aNorm, aNColor);
579 }
580 else
581 {
582 theArray->AddVertex (aPnt, aNColor);
583 }
584 }
585 }
586 }
587 }
588 }
589 else
590 {
591 // Find all pairs of nodes (edges) to draw (will be drawn only once)
592 NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap;
593
594 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
595 {
596 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
597
598 for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
599 {
600 const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
601
602 aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1),
603 aFaceNodes.Value (aNextIdx + 1)));
604 }
605 }
606
607 // Draw edges
608 for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next())
609 {
610 const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
611 const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
612
613 Standard_Real aX[] = { theCoords.Value (anIdx1 + 0), theCoords.Value (anIdx2 + 0) };
614 Standard_Real aY[] = { theCoords.Value (anIdx1 + 1), theCoords.Value (anIdx2 + 1) };
615 Standard_Real aZ[] = { theCoords.Value (anIdx1 + 2), theCoords.Value (anIdx2 + 2) };
616
617 theArray->AddVertex (aX[0], aY[0], aZ[0]);
618 theArray->AddVertex (aX[1], aY[1], aZ[1]);
619 }
620 }
621}
622
623//================================================================
7fd59977 624// Function : SetColors
625// Purpose :
626//================================================================
3c3131a0 627void MeshVS_NodalColorPrsBuilder::SetColors (
7fd59977 628 const MeshVS_DataMapOfIntegerColor& theColorMap )
629{
630 myNodeColorMap = theColorMap;
631}
632
633//================================================================
634// Function : GetColors
635// Purpose :
636//================================================================
637const MeshVS_DataMapOfIntegerColor& MeshVS_NodalColorPrsBuilder::GetColors() const
638{
639 return myNodeColorMap;
640}
641
642//================================================================
643// Function : HasColors
644// Purpose :
645//================================================================
646Standard_Boolean MeshVS_NodalColorPrsBuilder::HasColors () const
647{
648 return ( myNodeColorMap.Extent() >0 );
649}
650
651//================================================================
652// Function : GetColor
653// Purpose :
654//================================================================
655Standard_Boolean MeshVS_NodalColorPrsBuilder::GetColor ( const Standard_Integer ID,
656 Quantity_Color& theColor ) const
657{
658 Standard_Boolean aRes = myNodeColorMap.IsBound ( ID );
659 if ( aRes )
660 theColor = myNodeColorMap.Find ( ID );
661 return aRes;
662}
663
664//================================================================
665// Function : SetColor
666// Purpose :
667//================================================================
668void MeshVS_NodalColorPrsBuilder::SetColor ( const Standard_Integer theID,
669 const Quantity_Color& theCol )
670{
671 Standard_Boolean aRes = myNodeColorMap.IsBound ( theID );
672 if ( aRes )
673 myNodeColorMap.ChangeFind ( theID ) = theCol;
674 else
675 myNodeColorMap.Bind ( theID, theCol );
676}
677
678//================================================================
679// Function : UseTexture
680// Purpose : Specify whether texture must be used to build presentation
681//================================================================
682void MeshVS_NodalColorPrsBuilder::UseTexture( const Standard_Boolean theToUse )
683{
684 myUseTexture = theToUse;
685 if ( myUseTexture )
686 myNodeColorMap.Clear();
687 else
688 myTextureColorMap.Clear();
689}
690
691//================================================================
692// Function : IsUseTexture
693// Purpose : Verify whether texture is used to build presentation
694//================================================================
695Standard_Boolean MeshVS_NodalColorPrsBuilder::IsUseTexture() const
696{
697 return myUseTexture;
698}
699
700//================================================================
701// Function : SetColorMap
3c3131a0 702// Purpose : Set colors to be used for texrture presentation.
7fd59977 703// Generate texture in accordance with given parameters
704//================================================================
705void MeshVS_NodalColorPrsBuilder::SetColorMap( const Aspect_SequenceOfColor& theColors )
706{
707 myTextureColorMap = theColors;
708}
709
710//================================================================
711// Function : GetColorMap
3c3131a0 712// Purpose : Return colors used for texrture presentation
7fd59977 713//================================================================
714const Aspect_SequenceOfColor& MeshVS_NodalColorPrsBuilder::GetColorMap() const
715{
716 return myTextureColorMap;
717}
718
719//================================================================
720// Function : SetInvalidColor
3c3131a0 721// Purpose : Set color representing invalid texture coordinate
7fd59977 722// (laying outside range [0, 1])
723//================================================================
3c3131a0 724void MeshVS_NodalColorPrsBuilder::SetInvalidColor(
7fd59977 725 const Quantity_Color& theInvalidColor )
726{
727 myInvalidColor = theInvalidColor;
728}
729
730//================================================================
731// Function : GetInvalidColor
732// Purpose : Return color representing invalid texture coordinate
733// (laying outside range [0, 1])
734//================================================================
735Quantity_Color MeshVS_NodalColorPrsBuilder::GetInvalidColor() const
736{
737 return myInvalidColor;
738}
739
740//================================================================
741// Function : SetTextureCoords
3c3131a0 742// Purpose : Specify correspondence between node IDs and texture
7fd59977 743// coordinates (range [0, 1])
744//================================================================
3c3131a0 745void MeshVS_NodalColorPrsBuilder::SetTextureCoords (
7fd59977 746 const TColStd_DataMapOfIntegerReal& theMap )
747{
748 myTextureCoords = theMap;
749}
750
751//================================================================
752// Function : GetTextureCoords
3c3131a0 753// Purpose : Get correspondence between node IDs and texture
754// coordinates (range [0, 1])
7fd59977 755//================================================================
756const TColStd_DataMapOfIntegerReal& MeshVS_NodalColorPrsBuilder::GetTextureCoords() const
757{
758 return myTextureCoords;
759}
760
761//================================================================
762// Function : SetTextureCoord
3c3131a0 763// Purpose : Specify correspondence between node ID and texture
764// coordinate (range [0, 1])
7fd59977 765//================================================================
766void MeshVS_NodalColorPrsBuilder::SetTextureCoord( const Standard_Integer theID,
767 const Standard_Real theCoord )
768{
769 myTextureCoords.Bind( theID, theCoord );
770}
771
772//================================================================
773// Function : GetTextureCoord
3c3131a0 774// Purpose : Return correspondence between node IDs and texture
775// coordinate (range [0, 1])
7fd59977 776//================================================================
777Standard_Real MeshVS_NodalColorPrsBuilder::GetTextureCoord( const Standard_Integer theID )
778{
779 return myTextureCoords.IsBound( theID ) ? myTextureCoords( theID ) : -1;
780}
781
782//================================================================
783// Function : CreateTexture
784// Purpose : Create texture in accordance with myTextureColorMap
785//================================================================
786Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const
787{
3c3131a0 788 const Standard_Integer aColorsNb = myTextureColorMap.Length();
789 if (aColorsNb == 0)
790 {
791 return NULL;
792 }
7fd59977 793
3c3131a0 794 // create and fill image with colors
bf75be98 795 Handle(Image_PixMap) anImage = new Image_PixMap();
796 if (!anImage->InitTrash (Image_PixMap::ImgRGBA, Standard_Size(getNearestPow2 (aColorsNb)), 2))
3c3131a0 797 {
798 return NULL;
799 }
7fd59977 800
bf75be98 801 anImage->SetTopDown (false);
3c3131a0 802 for (Standard_Size aCol = 0; aCol < Standard_Size(aColorsNb); ++aCol)
803 {
804 const Quantity_Color& aSrcColor = myTextureColorMap.Value (Standard_Integer(aCol) + 1);
ca0c0b11 805 Image_ColorRGBA& aColor = anImage->ChangeValue<Image_ColorRGBA> (0, aCol);
8263fcd3 806 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
807 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
808 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
3c3131a0 809 aColor.a() = 0xFF;
810 }
7fd59977 811
3c3131a0 812 // fill padding bytes
813 const Quantity_Color& aLastColorSrc = myTextureColorMap.Last();
814 const Image_ColorRGBA aLastColor =
815 {{
8263fcd3 816 Standard_Byte(255.0 * aLastColorSrc.Red()),
817 Standard_Byte(255.0 * aLastColorSrc.Green()),
818 Standard_Byte(255.0 * aLastColorSrc.Blue()),
3c3131a0 819 0xFF
820 }};
821
822 // fill second row
bf75be98 823 for (Standard_Size aCol = (Standard_Size )aColorsNb; aCol < anImage->SizeX(); ++aCol)
7fd59977 824 {
ca0c0b11 825 anImage->ChangeValue<Image_ColorRGBA> (0, aCol) = aLastColor;
7fd59977 826 }
827
3c3131a0 828 const Image_ColorRGBA anInvalidColor =
829 {{
8263fcd3 830 Standard_Byte(255.0 * myInvalidColor.Red()),
831 Standard_Byte(255.0 * myInvalidColor.Green()),
832 Standard_Byte(255.0 * myInvalidColor.Blue()),
3c3131a0 833 0xFF
834 }};
bf75be98 835 for (Standard_Size aCol = 0; aCol < anImage->SizeX(); ++aCol)
3c3131a0 836 {
ca0c0b11 837 anImage->ChangeValue<Image_ColorRGBA> (1, aCol) = anInvalidColor;
3c3131a0 838 }
7fd59977 839
3c3131a0 840 // create texture
bf75be98 841 return new MeshVS_ImageTexture2D (anImage);
7fd59977 842}