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