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