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