| 1 | // Created on: 2003-11-12 |
| 2 | // Created by: Alexander SOLOVYOV |
| 3 | // Copyright (c) 2003-2012 OPEN CASCADE SAS |
| 4 | // |
| 5 | // The content of this file is subject to the Open CASCADE Technology Public |
| 6 | // License Version 6.5 (the "License"). You may not use the content of this file |
| 7 | // except in compliance with the License. Please obtain a copy of the License |
| 8 | // at http://www.opencascade.org and read it completely before using this file. |
| 9 | // |
| 10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
| 11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
| 12 | // |
| 13 | // The Original Code and all software distributed under the License is |
| 14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
| 15 | // Initial Developer hereby disclaims all such warranties, including without |
| 16 | // limitation, any warranties of merchantability, fitness for a particular |
| 17 | // purpose or non-infringement. Please see the License for the specific terms |
| 18 | // and conditions governing the rights and limitations under the License. |
| 19 | |
| 20 | |
| 21 | #define _POLYGONES_ |
| 22 | // if define _POLYGONES_ ColorPrsBuilder use ArrayOfPolygons for drawing faces |
| 23 | |
| 24 | #include <MeshVS_NodalColorPrsBuilder.ixx> |
| 25 | |
| 26 | #include <Graphic3d_AspectFillArea3d.hxx> |
| 27 | #include <Graphic3d_AspectLine3d.hxx> |
| 28 | #include <Graphic3d_ArrayOfPolygons.hxx> |
| 29 | #include <Graphic3d_ArrayOfPolylines.hxx> |
| 30 | #include <Graphic3d_Vertex.hxx> |
| 31 | #include <Graphic3d_Group.hxx> |
| 32 | #include <Graphic3d_Array1OfVertex.hxx> |
| 33 | |
| 34 | #include <Prs3d_ShadingAspect.hxx> |
| 35 | #include <Prs3d_Root.hxx> |
| 36 | #include <Prs3d_LineAspect.hxx> |
| 37 | |
| 38 | #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx> |
| 39 | #include <TColStd_ListIteratorOfListOfInteger.hxx> |
| 40 | #include <TColStd_Array1OfReal.hxx> |
| 41 | #include <TColStd_HArray1OfReal.hxx> |
| 42 | #include <TColStd_Array1OfInteger.hxx> |
| 43 | #include <TColStd_SequenceOfInteger.hxx> |
| 44 | #include <TColStd_HPackedMapOfInteger.hxx> |
| 45 | |
| 46 | #include <MeshVS_DisplayModeFlags.hxx> |
| 47 | #include <MeshVS_DrawerAttribute.hxx> |
| 48 | #include <MeshVS_DataSource.hxx> |
| 49 | #include <MeshVS_Drawer.hxx> |
| 50 | #include <MeshVS_Mesh.hxx> |
| 51 | #include <MeshVS_MeshPrsBuilder.hxx> |
| 52 | #include <MeshVS_HArray1OfSequenceOfInteger.hxx> |
| 53 | #include <MeshVS_Buffer.hxx> |
| 54 | |
| 55 | #include <gp_Pnt.hxx> |
| 56 | #include <Image_ColorImage.hxx> |
| 57 | #include <AlienImage_AlienImage.hxx> |
| 58 | #include <AlienImage_BMPAlienImage.hxx> |
| 59 | #include <Graphic3d_Texture2D.hxx> |
| 60 | #include <Graphic3d_TypeOfTextureMode.hxx> |
| 61 | #include <Standard_DefineHandle.hxx> |
| 62 | #include <PrsMgr_PresentationManager3d.hxx> |
| 63 | #include <Graphic3d_Array1OfVertexNT.hxx> |
| 64 | #include <AIS_Drawer.hxx> |
| 65 | #include <Quantity_Array1OfColor.hxx> |
| 66 | #include <Aspect_SequenceOfColor.hxx> |
| 67 | |
| 68 | /* |
| 69 | Class : MeshVS_ImageTexture2D |
| 70 | Description : Texture for nodal presentation |
| 71 | */ |
| 72 | class MeshVS_ImageTexture2D : public Graphic3d_Texture2D |
| 73 | { |
| 74 | public: |
| 75 | MeshVS_ImageTexture2D( Handle(Graphic3d_StructureManager) theSM, |
| 76 | const Handle(AlienImage_AlienImage)& theImg ); |
| 77 | virtual ~MeshVS_ImageTexture2D(); |
| 78 | |
| 79 | public: |
| 80 | DEFINE_STANDARD_RTTI(MeshVS_ImageTexture2D) |
| 81 | }; |
| 82 | |
| 83 | DEFINE_STANDARD_HANDLE(MeshVS_ImageTexture2D,Graphic3d_Texture2D) |
| 84 | IMPLEMENT_STANDARD_HANDLE(MeshVS_ImageTexture2D,Graphic3d_Texture2D) |
| 85 | IMPLEMENT_STANDARD_RTTIEXT(MeshVS_ImageTexture2D, Graphic3d_Texture2D) |
| 86 | |
| 87 | MeshVS_ImageTexture2D::MeshVS_ImageTexture2D |
| 88 | (Handle(Graphic3d_StructureManager) theSM, |
| 89 | const Handle(AlienImage_AlienImage)& theImg) |
| 90 | : Graphic3d_Texture2D( theSM, "", Graphic3d_TOT_2D ) |
| 91 | { |
| 92 | MyCInitTexture.doModulate = 1; |
| 93 | MyCInitTexture.doRepeat = 0; |
| 94 | MyCInitTexture.Mode = (int)Graphic3d_TOTM_MANUAL; |
| 95 | MyCInitTexture.doLinear = 1; |
| 96 | MyCInitTexture.sx = 1.0F; |
| 97 | MyCInitTexture.sy = 1.0F; |
| 98 | MyCInitTexture.tx = 0.0F; |
| 99 | MyCInitTexture.ty = 0.0F; |
| 100 | MyCInitTexture.angle = 0.0F; |
| 101 | MyCInitTexture.sparams[0] = 0.0F; |
| 102 | MyCInitTexture.sparams[1] = 0.0F; |
| 103 | MyCInitTexture.sparams[2] = 0.0F; |
| 104 | MyCInitTexture.sparams[3] = 0.0F; |
| 105 | MyCInitTexture.tparams[0] = 0.0F; |
| 106 | MyCInitTexture.tparams[1] = 0.0F; |
| 107 | MyCInitTexture.tparams[2] = 0.0F; |
| 108 | MyCInitTexture.tparams[3] = 0.0F; |
| 109 | Update(); |
| 110 | LoadTexture(theImg); |
| 111 | } |
| 112 | |
| 113 | MeshVS_ImageTexture2D::~MeshVS_ImageTexture2D() |
| 114 | { |
| 115 | } |
| 116 | |
| 117 | //================================================================ |
| 118 | // Function : getNearestPow2 |
| 119 | // Purpose : Returns the nearest power of two greater than the |
| 120 | // argument value |
| 121 | //================================================================ |
| 122 | static inline Standard_Integer getNearestPow2( Standard_Integer theValue ) |
| 123 | { |
| 124 | // Precaution against overflow |
| 125 | Standard_Integer aHalfMax = IntegerLast() >> 1, aRes = 1; |
| 126 | if ( theValue > aHalfMax ) theValue = aHalfMax; |
| 127 | while ( aRes < theValue ) aRes <<= 1; |
| 128 | return aRes; |
| 129 | } |
| 130 | |
| 131 | /* |
| 132 | Class : MeshVS_NodalColorPrsBuilder |
| 133 | Description : This class provides methods to create presentation of |
| 134 | nodes with assigned color (See hxx for more description ) |
| 135 | */ |
| 136 | |
| 137 | //================================================================ |
| 138 | // Function : Constructor MeshVS_NodalColorPrsBuilder |
| 139 | // Purpose : |
| 140 | //================================================================ |
| 141 | MeshVS_NodalColorPrsBuilder::MeshVS_NodalColorPrsBuilder ( const Handle(MeshVS_Mesh)& Parent, |
| 142 | const MeshVS_DisplayModeFlags& Flags, |
| 143 | const Handle (MeshVS_DataSource)& DS, |
| 144 | const Standard_Integer Id, |
| 145 | const MeshVS_BuilderPriority& Priority ) |
| 146 | : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ), |
| 147 | myUseTexture( Standard_False ), |
| 148 | myInvalidColor( Quantity_NOC_GRAY ) |
| 149 | { |
| 150 | SetExcluding ( Standard_True ); |
| 151 | } |
| 152 | |
| 153 | //================================================================ |
| 154 | // Function : Build |
| 155 | // Purpose : |
| 156 | //================================================================ |
| 157 | void MeshVS_NodalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, |
| 158 | const TColStd_PackedMapOfInteger& IDs, |
| 159 | TColStd_PackedMapOfInteger& IDsToExclude, |
| 160 | const Standard_Boolean IsElement, |
| 161 | const Standard_Integer DisplayMode) const |
| 162 | { |
| 163 | Handle (MeshVS_DataSource) aSource = GetDataSource(); |
| 164 | Handle (MeshVS_Drawer) aDrawer = GetDrawer(); |
| 165 | if ( aSource.IsNull() || aDrawer.IsNull() ) |
| 166 | return; |
| 167 | |
| 168 | Standard_Integer aMaxFaceNodes; |
| 169 | if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) || aMaxFaceNodes <= 0 ) |
| 170 | return; |
| 171 | |
| 172 | MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real)); |
| 173 | TColStd_Array1OfReal aCoords ( aCoordsBuf, 1, 3 * aMaxFaceNodes ); |
| 174 | Standard_Integer NbNodes; |
| 175 | MeshVS_EntityType aType; |
| 176 | |
| 177 | if ( !( DisplayMode & GetFlags() ) || !IsElement ) |
| 178 | return; |
| 179 | |
| 180 | if ( myUseTexture && ( !myTextureCoords.Extent() || !myTextureColorMap.Length() ) || |
| 181 | !myUseTexture && !myNodeColorMap.Extent() ) |
| 182 | return; |
| 183 | |
| 184 | // subtract the hidden elements and ids to exclude (to minimise allocated memory) |
| 185 | TColStd_PackedMapOfInteger anIDs; |
| 186 | anIDs.Assign( IDs ); |
| 187 | Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems(); |
| 188 | if ( !aHiddenElems.IsNull() ) |
| 189 | anIDs.Subtract( aHiddenElems->Map() ); |
| 190 | anIDs.Subtract( IDsToExclude ); |
| 191 | |
| 192 | Standard_Boolean IsReflect = Standard_False, IsMeshSmoothShading = Standard_False; |
| 193 | aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect ); |
| 194 | aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading ); |
| 195 | |
| 196 | // Following parameter are used for texture presentation only |
| 197 | int nbColors = 0; // Number of colors from color map |
| 198 | int nbTextureColors = 0; // Number of colors in texture (it will be pow of 2) |
| 199 | if ( myUseTexture ) |
| 200 | { |
| 201 | nbColors = myTextureColorMap.Length(); |
| 202 | nbTextureColors = getNearestPow2( nbColors ); |
| 203 | } |
| 204 | |
| 205 | Standard_Integer aSize = anIDs.Extent(); |
| 206 | |
| 207 | // Calculate maximum possible number of vertices and bounds |
| 208 | Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo; |
| 209 | Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0; |
| 210 | TColStd_MapIteratorOfPackedMapOfInteger it (anIDs); |
| 211 | for( ; it.More(); it.Next() ) |
| 212 | { |
| 213 | Standard_Integer aKey = it.Key(); |
| 214 | if ( aSource->Get3DGeom( aKey, NbNodes, aTopo ) ) |
| 215 | MeshVS_MeshPrsBuilder::HowManyPrimitives |
| 216 | ( aTopo, Standard_True, Standard_False, NbNodes, |
| 217 | PolygonVerticesFor3D, PolygonBoundsFor3D ); |
| 218 | } |
| 219 | |
| 220 | // Draw faces with nodal color |
| 221 | // OCC20644 Use "plastic" material as it is "non-physic" and so it is easier |
| 222 | // to get the required colors (see TelUpdateMaterial() function in OpenGl_attri.c) |
| 223 | Graphic3d_MaterialAspect aMaterial[ 2 ]; |
| 224 | aMaterial[ 0 ] = Graphic3d_MaterialAspect( Graphic3d_NOM_PLASTIC ); |
| 225 | aMaterial[ 1 ] = Graphic3d_MaterialAspect( Graphic3d_NOM_PLASTIC ); |
| 226 | Standard_Integer i; |
| 227 | for ( i = 0; i < 2; i++ ) |
| 228 | { |
| 229 | if ( !IsReflect ) |
| 230 | { |
| 231 | aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_SPECULAR ); |
| 232 | aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_AMBIENT ); |
| 233 | aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_DIFFUSE ); |
| 234 | aMaterial[ i ].SetReflectionModeOff( Graphic3d_TOR_EMISSION ); |
| 235 | } |
| 236 | else{ |
| 237 | // OCC20644 Using the material with reflection properties same as in |
| 238 | // ElementalColorPrsBuilder, to get the same colors. |
| 239 | // Additionally, ambient and diffuse coefficients are used below to scale incoming colors, |
| 240 | // to simulate TelUpdateMaterial() function from OpenGl_attri.c. |
| 241 | // This is mandatory, as these "scaled" colors are then passed directly to OpenGL |
| 242 | // as ambient and diffuse colors of the current material using glColorMaterial(). |
| 243 | // In ElementalColorPrsBuilder we do not need to do scale the colors, as this |
| 244 | // is done by TelUpdateMaterial(). |
| 245 | // 0.5 is used to have the colors in 3D maximally similar to those in the color scale. |
| 246 | // This is possible when the sum of all coefficient is equal to 1. |
| 247 | aMaterial[i].SetAmbient( .5 ); |
| 248 | aMaterial[i].SetDiffuse( .5 ); |
| 249 | aMaterial[i].SetSpecular( 0. ); |
| 250 | aMaterial[i].SetEmissive( 0. ); |
| 251 | } |
| 252 | |
| 253 | } |
| 254 | |
| 255 | |
| 256 | // Create array of polygons for interior presentation of faces and volumes |
| 257 | Handle(Graphic3d_ArrayOfPolygons) aCPolyArr = new Graphic3d_ArrayOfPolygons |
| 258 | ( aMaxFaceNodes * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D, |
| 259 | 0, myUseTexture || IsReflect, !myUseTexture, Standard_False, myUseTexture ); |
| 260 | |
| 261 | // Create array of polylines for presentation of edges |
| 262 | // (used for optimization insted of SetEdgeOn method call) |
| 263 | Handle(Graphic3d_ArrayOfPolylines) aPolyL = new Graphic3d_ArrayOfPolylines |
| 264 | ( ( aMaxFaceNodes + 1 ) * aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D ); |
| 265 | |
| 266 | gp_Pnt P, Start; |
| 267 | Standard_Real aMin = gp::Resolution() * gp::Resolution(); |
| 268 | gp_Dir aDefNorm( 0., 0., 1. ); |
| 269 | |
| 270 | // Prepare for scaling the incoming colors |
| 271 | Standard_Real anColorRatio = aMaterial[0].Ambient(); |
| 272 | |
| 273 | for( it.Reset(); it.More(); it.Next() ) |
| 274 | { |
| 275 | Standard_Integer aKey = it.Key(); |
| 276 | if ( aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) ) |
| 277 | { |
| 278 | MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer)); |
| 279 | TColStd_Array1OfInteger aNodes(aNodesBuf, 1, NbNodes); |
| 280 | if ( !aSource->GetNodesByElement ( aKey, aNodes, NbNodes ) ) |
| 281 | continue; |
| 282 | |
| 283 | Quantity_Color aNColor; |
| 284 | |
| 285 | Standard_Boolean isValid = Standard_True; |
| 286 | Standard_Integer i; |
| 287 | if ( myUseTexture ) |
| 288 | { |
| 289 | for ( i = 1; i <= NbNodes && isValid; i++ ) |
| 290 | isValid = myTextureCoords.IsBound( aNodes( i ) ); |
| 291 | } |
| 292 | else |
| 293 | { |
| 294 | for ( i = 1; i <= NbNodes && isValid; i++ ) |
| 295 | isValid = GetColor ( aNodes( i ), aNColor ); |
| 296 | } |
| 297 | |
| 298 | if ( !isValid ) |
| 299 | continue; |
| 300 | |
| 301 | // Preparing normal(s) to show reflections if requested |
| 302 | Handle(TColStd_HArray1OfReal) aNormals; |
| 303 | Standard_Boolean hasNormals = |
| 304 | ( IsReflect && aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals ) ); |
| 305 | |
| 306 | if ( aType == MeshVS_ET_Face ) |
| 307 | { |
| 308 | aCPolyArr->AddBound ( NbNodes ); |
| 309 | aPolyL->AddBound ( NbNodes + 1 ); |
| 310 | |
| 311 | for ( i = 1; i <= NbNodes; i++) |
| 312 | { |
| 313 | P = gp_Pnt( aCoords( 3 * i - 2 ), aCoords( 3 * i - 1 ), aCoords( 3 * i ) ); |
| 314 | if ( myUseTexture ) |
| 315 | { |
| 316 | int anId = aNodes( i ); |
| 317 | double aTexCoord = myTextureCoords( anId ); |
| 318 | |
| 319 | // transform texture coordinate in accordance with number of colors specified |
| 320 | // by upper level and real size of Gl texture |
| 321 | // The Gl texture has border colors interpolated with the colors from the color map, |
| 322 | // thats why we need to shrink texture coordinates around the middle point to |
| 323 | // exclude areas where the map colors are interpolated with the borders color |
| 324 | double aWrapCoord = 1.0 / (2.0 * nbTextureColors) + aTexCoord * (nbColors - 1.0) / nbTextureColors; |
| 325 | |
| 326 | if ( hasNormals ) |
| 327 | { |
| 328 | gp_Vec aNorm(aNormals->Value( 3 * i - 2 ), |
| 329 | aNormals->Value( 3 * i - 1 ), |
| 330 | aNormals->Value( 3 * i )); |
| 331 | // There are two "rows" of colors: user's invalid color at the top |
| 332 | // of texture and line of map colors at the bottom of the texture. |
| 333 | // Since the texture has borders, which are interpolated with the "rows" of colors |
| 334 | // we should specify the 0.25 offset to get the correct texture color |
| 335 | aNorm.SquareMagnitude() > aMin ? |
| 336 | aCPolyArr->AddVertex(P, gp_Dir( aNorm ), |
| 337 | gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ) : |
| 338 | aCPolyArr->AddVertex(P, aDefNorm, |
| 339 | gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ); |
| 340 | } |
| 341 | else |
| 342 | aCPolyArr->AddVertex( P, aDefNorm, |
| 343 | gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ); |
| 344 | } |
| 345 | else |
| 346 | { |
| 347 | GetColor ( aNodes( i ), aNColor ); |
| 348 | |
| 349 | if ( IsReflect ) |
| 350 | { |
| 351 | // Simulating TelUpdateMaterial() from OpenGl_attri.c |
| 352 | // to get the same colors in elemental and nodal color prs builders |
| 353 | aNColor.SetValues(anColorRatio * aNColor.Red(), |
| 354 | anColorRatio * aNColor.Green(), |
| 355 | anColorRatio * aNColor.Blue(), |
| 356 | Quantity_TOC_RGB); |
| 357 | |
| 358 | if ( hasNormals ) |
| 359 | { |
| 360 | gp_Vec aNorm(aNormals->Value( 3 * i - 2 ), |
| 361 | aNormals->Value( 3 * i - 1 ), |
| 362 | aNormals->Value( 3 * i )); |
| 363 | aNorm.SquareMagnitude() > aMin ? |
| 364 | aCPolyArr->AddVertex(P, gp_Dir( aNorm ), aNColor ) : |
| 365 | aCPolyArr->AddVertex(P, aDefNorm , aNColor ); |
| 366 | } |
| 367 | else |
| 368 | aCPolyArr->AddVertex(P, aDefNorm, aNColor ); |
| 369 | } |
| 370 | else |
| 371 | aCPolyArr->AddVertex( P, aNColor ); |
| 372 | } |
| 373 | aPolyL->AddVertex ( P ); |
| 374 | if ( i == 1 ) |
| 375 | Start = P; |
| 376 | } |
| 377 | aPolyL->AddVertex ( Start ); |
| 378 | |
| 379 | // if IsExcludingOn then presentation must not be built by other builders |
| 380 | if ( IsExcludingOn() ) |
| 381 | IDsToExclude.Add( aKey ); |
| 382 | } |
| 383 | else if ( aType == MeshVS_ET_Volume ) |
| 384 | { |
| 385 | if ( !aSource->Get3DGeom( aKey, NbNodes, aTopo ) ) |
| 386 | continue; |
| 387 | |
| 388 | // iterate through faces of volume |
| 389 | for ( Standard_Integer k = aTopo->Lower(), last = aTopo->Upper(), normIndex = 1; k <= last; k++, normIndex++ ) |
| 390 | { |
| 391 | const TColStd_SequenceOfInteger& aSeq = aTopo->Value( k ); |
| 392 | Standard_Integer m = aSeq.Length(), ind; |
| 393 | |
| 394 | // build polygon & polylines for current face |
| 395 | aCPolyArr->AddBound( m ); |
| 396 | aPolyL->AddBound( m + 1 ); |
| 397 | for ( Standard_Integer j = 1; j <= m; j++ ) |
| 398 | { |
| 399 | ind = aSeq.Value( j ); |
| 400 | P = gp_Pnt( aCoords( 3 * ind + 1 ), |
| 401 | aCoords( 3 * ind + 2 ), |
| 402 | aCoords( 3 * ind + 3 ) ); |
| 403 | if ( myUseTexture ) |
| 404 | { |
| 405 | Standard_Integer anId = aNodes( ind + 1 ); |
| 406 | Standard_Real aTexCoord = myTextureCoords( anId ); |
| 407 | |
| 408 | // transform texture coordinate in accordance with number of colors specified |
| 409 | // by upper level and real size of Gl texture |
| 410 | // The Gl texture has border colors interpolated with the colors from the color map, |
| 411 | // thats why we need to shrink texture coordinates around the middle point to |
| 412 | // exclude areas where the map colors are interpolated with the borders color |
| 413 | double aWrapCoord = 1.0 / (2.0 * nbTextureColors) + aTexCoord * (nbColors - 1.0) / nbTextureColors; |
| 414 | |
| 415 | if ( hasNormals ) |
| 416 | { |
| 417 | gp_Vec aNorm(aNormals->Value( 3 * i - 2 ), |
| 418 | aNormals->Value( 3 * i - 1 ), |
| 419 | aNormals->Value( 3 * i )); |
| 420 | // There are two "rows" of colors: user's invalid color at the top |
| 421 | // of texture and line of map colors at the bottom of the texture. |
| 422 | // Since the texture has borders, which are interpolated with the "rows" of colors |
| 423 | // we should specify the 0.25 offset to get the correct texture color |
| 424 | aNorm.SquareMagnitude() > aMin ? |
| 425 | aCPolyArr->AddVertex(P, gp_Dir( aNorm ), |
| 426 | gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ) : |
| 427 | aCPolyArr->AddVertex(P, aDefNorm, |
| 428 | gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ); |
| 429 | } |
| 430 | else |
| 431 | aCPolyArr->AddVertex( P, aDefNorm, |
| 432 | gp_Pnt2d( aWrapCoord, aTexCoord >= 0 && aTexCoord <= 1 ? 0.75 : 0.25 ) ); |
| 433 | } |
| 434 | else |
| 435 | { |
| 436 | GetColor( aNodes( ind + 1 ), aNColor ); |
| 437 | if ( IsReflect ) |
| 438 | { |
| 439 | // Simulating TelUpdateMaterial() from OpenGl_attri.c |
| 440 | // to get the same colors in elemental and nodal color prs builders |
| 441 | aNColor.SetValues(anColorRatio * aNColor.Red(), |
| 442 | anColorRatio * aNColor.Green(), |
| 443 | anColorRatio * aNColor.Blue(), |
| 444 | Quantity_TOC_RGB); |
| 445 | |
| 446 | if ( hasNormals ) |
| 447 | { |
| 448 | gp_Vec aNorm(aNormals->Value( 3 * normIndex - 2 ), |
| 449 | aNormals->Value( 3 * normIndex - 1 ), |
| 450 | aNormals->Value( 3 * normIndex )); |
| 451 | aNorm.SquareMagnitude() > aMin ? |
| 452 | aCPolyArr->AddVertex( P, gp_Dir( aNorm ), aNColor ) : |
| 453 | aCPolyArr->AddVertex( P, aDefNorm , aNColor ); |
| 454 | } |
| 455 | else |
| 456 | aCPolyArr->AddVertex( P, aDefNorm, aNColor ); |
| 457 | } |
| 458 | else |
| 459 | aCPolyArr->AddVertex( P, aNColor ); |
| 460 | } |
| 461 | aPolyL->AddVertex ( P ); |
| 462 | if ( j == 1 ) |
| 463 | Start = P; |
| 464 | } |
| 465 | aPolyL->AddVertex ( Start ); |
| 466 | } |
| 467 | |
| 468 | // if IsExcludingOn then presentation must not be built by other builders |
| 469 | if ( IsExcludingOn() ) |
| 470 | IDsToExclude.Add( aKey ); |
| 471 | } |
| 472 | } |
| 473 | } // for ( ... |
| 474 | |
| 475 | Handle(Graphic3d_AspectFillArea3d) anAsp; |
| 476 | |
| 477 | // Aspect_InteriorStyle aStyle; |
| 478 | // Standard_Integer aStyleInt; |
| 479 | Aspect_TypeOfLine anEdgeType = Aspect_TOL_SOLID; |
| 480 | Standard_Integer anEdgeInt; |
| 481 | Standard_Real anEdgeWidth; |
| 482 | Quantity_Color anInteriorColor; |
| 483 | Quantity_Color anEdgeColor, aLineColor; |
| 484 | Standard_Boolean aShowEdges = Standard_True; |
| 485 | |
| 486 | aDrawer->GetColor ( MeshVS_DA_InteriorColor, anInteriorColor ); |
| 487 | aDrawer->GetColor ( MeshVS_DA_EdgeColor, anEdgeColor ); |
| 488 | aDrawer->GetColor ( MeshVS_DA_BeamColor, aLineColor ); |
| 489 | aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth ); |
| 490 | aDrawer->GetBoolean( MeshVS_DA_ShowEdges, aShowEdges ); |
| 491 | |
| 492 | if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt ) ) |
| 493 | anEdgeType = (Aspect_TypeOfLine) anEdgeInt; |
| 494 | |
| 495 | if ( myUseTexture ) |
| 496 | { |
| 497 | Handle(AIS_Drawer) anAISDrawer = myParentMesh->Attributes(); |
| 498 | if ( anAISDrawer.IsNull() ) |
| 499 | return; |
| 500 | |
| 501 | anAISDrawer->SetShadingAspect( new Prs3d_ShadingAspect() ); |
| 502 | anAsp = anAISDrawer->ShadingAspect()->Aspect(); |
| 503 | if ( anAsp.IsNull() ) |
| 504 | return; |
| 505 | |
| 506 | anAsp->SetFrontMaterial( aMaterial[ 0 ] ); |
| 507 | anAsp->SetBackMaterial( aMaterial[ 1 ] ); |
| 508 | |
| 509 | |
| 510 | Handle(Graphic3d_Texture2D) aTexture = CreateTexture(); |
| 511 | if ( aTexture.IsNull() ) |
| 512 | return; |
| 513 | |
| 514 | anAsp->SetTextureMapOn(); |
| 515 | anAsp->SetTextureMap( aTexture ); |
| 516 | anAsp->SetInteriorColor( Quantity_NOC_WHITE ); |
| 517 | } |
| 518 | else |
| 519 | { |
| 520 | // if ( aDrawer->GetInteger ( MeshVS_DA_InteriorStyle, aStyleInt ) ) |
| 521 | // aStyle = (Aspect_InteriorStyle)aStyleInt; |
| 522 | |
| 523 | anAsp = new Graphic3d_AspectFillArea3d ( |
| 524 | Aspect_IS_SOLID, Quantity_NOC_GRAY, anEdgeColor, |
| 525 | anEdgeType, anEdgeWidth, aMaterial[ 0 ], aMaterial[ 1 ] ); |
| 526 | } |
| 527 | |
| 528 | anAsp->SetDistinguishOff(); |
| 529 | anAsp->SetEdgeOff(); |
| 530 | |
| 531 | Handle(Graphic3d_AspectLine3d) anLAsp = |
| 532 | new Graphic3d_AspectLine3d( anEdgeColor, anEdgeType, anEdgeWidth ); |
| 533 | |
| 534 | Prs3d_Root::NewGroup ( Prs ); |
| 535 | Handle(Graphic3d_Group) aGroup1 = Prs3d_Root::CurrentGroup ( Prs ); |
| 536 | |
| 537 | aGroup1->SetPrimitivesAspect( anAsp ); |
| 538 | aGroup1->BeginPrimitives(); |
| 539 | aGroup1->AddPrimitiveArray( aCPolyArr ); |
| 540 | aGroup1->EndPrimitives(); |
| 541 | |
| 542 | if (aShowEdges) |
| 543 | { |
| 544 | Prs3d_Root::NewGroup ( Prs ); |
| 545 | Handle(Graphic3d_Group) aGroup2 = Prs3d_Root::CurrentGroup ( Prs ); |
| 546 | |
| 547 | anAsp->SetEdgeOff(); |
| 548 | anAsp->SetTextureMapOff(); |
| 549 | aGroup2->SetPrimitivesAspect( anAsp ); |
| 550 | aGroup2->SetPrimitivesAspect( anLAsp ); |
| 551 | aGroup2->BeginPrimitives(); |
| 552 | aGroup2->AddPrimitiveArray( aPolyL ); |
| 553 | aGroup2->EndPrimitives(); |
| 554 | anAsp->SetEdgeOn(); |
| 555 | } |
| 556 | } |
| 557 | |
| 558 | //================================================================ |
| 559 | // Function : SetColors |
| 560 | // Purpose : |
| 561 | //================================================================ |
| 562 | void MeshVS_NodalColorPrsBuilder::SetColors ( |
| 563 | const MeshVS_DataMapOfIntegerColor& theColorMap ) |
| 564 | { |
| 565 | myNodeColorMap = theColorMap; |
| 566 | } |
| 567 | |
| 568 | //================================================================ |
| 569 | // Function : GetColors |
| 570 | // Purpose : |
| 571 | //================================================================ |
| 572 | const MeshVS_DataMapOfIntegerColor& MeshVS_NodalColorPrsBuilder::GetColors() const |
| 573 | { |
| 574 | return myNodeColorMap; |
| 575 | } |
| 576 | |
| 577 | //================================================================ |
| 578 | // Function : HasColors |
| 579 | // Purpose : |
| 580 | //================================================================ |
| 581 | Standard_Boolean MeshVS_NodalColorPrsBuilder::HasColors () const |
| 582 | { |
| 583 | return ( myNodeColorMap.Extent() >0 ); |
| 584 | } |
| 585 | |
| 586 | //================================================================ |
| 587 | // Function : GetColor |
| 588 | // Purpose : |
| 589 | //================================================================ |
| 590 | Standard_Boolean MeshVS_NodalColorPrsBuilder::GetColor ( const Standard_Integer ID, |
| 591 | Quantity_Color& theColor ) const |
| 592 | { |
| 593 | Standard_Boolean aRes = myNodeColorMap.IsBound ( ID ); |
| 594 | if ( aRes ) |
| 595 | theColor = myNodeColorMap.Find ( ID ); |
| 596 | return aRes; |
| 597 | } |
| 598 | |
| 599 | //================================================================ |
| 600 | // Function : SetColor |
| 601 | // Purpose : |
| 602 | //================================================================ |
| 603 | void MeshVS_NodalColorPrsBuilder::SetColor ( const Standard_Integer theID, |
| 604 | const Quantity_Color& theCol ) |
| 605 | { |
| 606 | Standard_Boolean aRes = myNodeColorMap.IsBound ( theID ); |
| 607 | if ( aRes ) |
| 608 | myNodeColorMap.ChangeFind ( theID ) = theCol; |
| 609 | else |
| 610 | myNodeColorMap.Bind ( theID, theCol ); |
| 611 | } |
| 612 | |
| 613 | //================================================================ |
| 614 | // Function : UseTexture |
| 615 | // Purpose : Specify whether texture must be used to build presentation |
| 616 | //================================================================ |
| 617 | void MeshVS_NodalColorPrsBuilder::UseTexture( const Standard_Boolean theToUse ) |
| 618 | { |
| 619 | myUseTexture = theToUse; |
| 620 | if ( myUseTexture ) |
| 621 | myNodeColorMap.Clear(); |
| 622 | else |
| 623 | myTextureColorMap.Clear(); |
| 624 | } |
| 625 | |
| 626 | //================================================================ |
| 627 | // Function : IsUseTexture |
| 628 | // Purpose : Verify whether texture is used to build presentation |
| 629 | //================================================================ |
| 630 | Standard_Boolean MeshVS_NodalColorPrsBuilder::IsUseTexture() const |
| 631 | { |
| 632 | return myUseTexture; |
| 633 | } |
| 634 | |
| 635 | //================================================================ |
| 636 | // Function : SetColorMap |
| 637 | // Purpose : Set colors to be used for texrture presentation. |
| 638 | // Generate texture in accordance with given parameters |
| 639 | //================================================================ |
| 640 | void MeshVS_NodalColorPrsBuilder::SetColorMap( const Aspect_SequenceOfColor& theColors ) |
| 641 | { |
| 642 | myTextureColorMap = theColors; |
| 643 | } |
| 644 | |
| 645 | //================================================================ |
| 646 | // Function : GetColorMap |
| 647 | // Purpose : Return colors used for texrture presentation |
| 648 | //================================================================ |
| 649 | const Aspect_SequenceOfColor& MeshVS_NodalColorPrsBuilder::GetColorMap() const |
| 650 | { |
| 651 | return myTextureColorMap; |
| 652 | } |
| 653 | |
| 654 | //================================================================ |
| 655 | // Function : SetInvalidColor |
| 656 | // Purpose : Set color representing invalid texture coordinate |
| 657 | // (laying outside range [0, 1]) |
| 658 | //================================================================ |
| 659 | void MeshVS_NodalColorPrsBuilder::SetInvalidColor( |
| 660 | const Quantity_Color& theInvalidColor ) |
| 661 | { |
| 662 | myInvalidColor = theInvalidColor; |
| 663 | } |
| 664 | |
| 665 | //================================================================ |
| 666 | // Function : GetInvalidColor |
| 667 | // Purpose : Return color representing invalid texture coordinate |
| 668 | // (laying outside range [0, 1]) |
| 669 | //================================================================ |
| 670 | Quantity_Color MeshVS_NodalColorPrsBuilder::GetInvalidColor() const |
| 671 | { |
| 672 | return myInvalidColor; |
| 673 | } |
| 674 | |
| 675 | //================================================================ |
| 676 | // Function : SetTextureCoords |
| 677 | // Purpose : Specify correspondence between node IDs and texture |
| 678 | // coordinates (range [0, 1]) |
| 679 | //================================================================ |
| 680 | void MeshVS_NodalColorPrsBuilder::SetTextureCoords ( |
| 681 | const TColStd_DataMapOfIntegerReal& theMap ) |
| 682 | { |
| 683 | myTextureCoords = theMap; |
| 684 | } |
| 685 | |
| 686 | //================================================================ |
| 687 | // Function : GetTextureCoords |
| 688 | // Purpose : Get correspondence between node IDs and texture |
| 689 | // coordinates (range [0, 1]) |
| 690 | //================================================================ |
| 691 | const TColStd_DataMapOfIntegerReal& MeshVS_NodalColorPrsBuilder::GetTextureCoords() const |
| 692 | { |
| 693 | return myTextureCoords; |
| 694 | } |
| 695 | |
| 696 | //================================================================ |
| 697 | // Function : SetTextureCoord |
| 698 | // Purpose : Specify correspondence between node ID and texture |
| 699 | // coordinate (range [0, 1]) |
| 700 | //================================================================ |
| 701 | void MeshVS_NodalColorPrsBuilder::SetTextureCoord( const Standard_Integer theID, |
| 702 | const Standard_Real theCoord ) |
| 703 | { |
| 704 | myTextureCoords.Bind( theID, theCoord ); |
| 705 | } |
| 706 | |
| 707 | //================================================================ |
| 708 | // Function : GetTextureCoord |
| 709 | // Purpose : Return correspondence between node IDs and texture |
| 710 | // coordinate (range [0, 1]) |
| 711 | //================================================================ |
| 712 | Standard_Real MeshVS_NodalColorPrsBuilder::GetTextureCoord( const Standard_Integer theID ) |
| 713 | { |
| 714 | return myTextureCoords.IsBound( theID ) ? myTextureCoords( theID ) : -1; |
| 715 | } |
| 716 | |
| 717 | //================================================================ |
| 718 | // Function : CreateTexture |
| 719 | // Purpose : Create texture in accordance with myTextureColorMap |
| 720 | //================================================================ |
| 721 | Handle(Graphic3d_Texture2D) MeshVS_NodalColorPrsBuilder::CreateTexture() const |
| 722 | { |
| 723 | Handle(Graphic3d_Texture2D) aTexture; |
| 724 | |
| 725 | int nbColors = myTextureColorMap.Length(); |
| 726 | if ( nbColors == 0 ) |
| 727 | return aTexture; |
| 728 | |
| 729 | Handle(PrsMgr_PresentationManager3d) aPrsMgr = GetPresentationManager(); |
| 730 | if ( aPrsMgr.IsNull() ) |
| 731 | return aTexture; |
| 732 | |
| 733 | int nbTextureColors = getNearestPow2( nbColors ); |
| 734 | |
| 735 | // Create and fill image with colors |
| 736 | Handle(Image_ColorImage) aCImage = |
| 737 | new Image_ColorImage( 0, 0, nbTextureColors, 2 ); |
| 738 | |
| 739 | if ( nbColors > 0 ) |
| 740 | { |
| 741 | int i; |
| 742 | for ( i = 0; i < nbColors; i++ ) |
| 743 | { |
| 744 | aCImage->SetPixel( i, 0, Aspect_ColorPixel( myTextureColorMap( i + 1 ) ) ); |
| 745 | aCImage->SetPixel( i, 1, Aspect_ColorPixel( myInvalidColor ) ); |
| 746 | } |
| 747 | Quantity_Color aLastColor = myTextureColorMap( nbColors ); |
| 748 | for ( i = nbColors; i < nbTextureColors; i++ ) |
| 749 | { |
| 750 | aCImage->SetPixel( i, 0, aLastColor ); |
| 751 | aCImage->SetPixel( i, 1, Aspect_ColorPixel( myInvalidColor ) ); |
| 752 | } |
| 753 | } |
| 754 | |
| 755 | // Convert image to bmp |
| 756 | Handle(AlienImage_BMPAlienImage) aTextureImage = new AlienImage_BMPAlienImage(); |
| 757 | aTextureImage->FromImage( aCImage ); |
| 758 | |
| 759 | // Create texture |
| 760 | aTexture = new MeshVS_ImageTexture2D( aPrsMgr->StructureManager(), aTextureImage ); |
| 761 | return aTexture; |
| 762 | } |