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