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 | |
7fd59977 |
16 | #include <MeshVS_ElementalColorPrsBuilder.ixx> |
17 | |
18 | #include <Graphic3d_AspectFillArea3d.hxx> |
19 | #include <Graphic3d_AspectLine3d.hxx> |
20 | #include <Graphic3d_ArrayOfPolygons.hxx> |
21 | #include <Graphic3d_ArrayOfPolylines.hxx> |
7fd59977 |
22 | #include <Graphic3d_Group.hxx> |
7fd59977 |
23 | |
24 | #include <Prs3d_ShadingAspect.hxx> |
25 | #include <Prs3d_Root.hxx> |
26 | #include <Prs3d_LineAspect.hxx> |
27 | |
28 | #include <TColStd_MapOfInteger.hxx> |
29 | #include <TColStd_PackedMapOfInteger.hxx> |
30 | #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx> |
31 | #include <TColStd_ListIteratorOfListOfInteger.hxx> |
32 | #include <TColStd_Array1OfReal.hxx> |
33 | #include <TColStd_SequenceOfInteger.hxx> |
34 | #include <TColStd_HArray1OfReal.hxx> |
35 | #include <TColStd_HPackedMapOfInteger.hxx> |
36 | |
37 | #include <MeshVS_DisplayModeFlags.hxx> |
38 | #include <MeshVS_DataSource.hxx> |
39 | #include <MeshVS_Mesh.hxx> |
40 | #include <MeshVS_DataMapOfColorMapOfInteger.hxx> |
41 | #include <MeshVS_DataMapOfTwoColorsMapOfInteger.hxx> |
42 | #include <MeshVS_Drawer.hxx> |
43 | #include <MeshVS_DrawerAttribute.hxx> |
44 | #include <MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors.hxx> |
45 | #include <MeshVS_DataMapIteratorOfDataMapOfIntegerColor.hxx> |
46 | #include <MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger.hxx> |
47 | #include <MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx> |
48 | #include <MeshVS_MeshPrsBuilder.hxx> |
49 | #include <MeshVS_Buffer.hxx> |
50 | |
51 | |
52 | //================================================================ |
53 | // Function : Constructor MeshVS_ElementalColorPrsBuilder |
54 | // Purpose : |
55 | //================================================================ |
56 | MeshVS_ElementalColorPrsBuilder::MeshVS_ElementalColorPrsBuilder |
57 | ( const Handle(MeshVS_Mesh)& Parent, |
58 | const MeshVS_DisplayModeFlags& Flags, |
59 | const Handle (MeshVS_DataSource)& DS, |
60 | const Standard_Integer Id, |
61 | const MeshVS_BuilderPriority& Priority ) |
62 | : MeshVS_PrsBuilder ( Parent, Flags, DS, Id, Priority ) |
63 | { |
64 | SetExcluding ( Standard_True ); |
65 | } |
66 | |
67 | //================================================================ |
68 | // Function : Build |
69 | // Purpose : |
70 | //================================================================ |
71 | void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs, |
72 | const TColStd_PackedMapOfInteger& IDs, |
73 | TColStd_PackedMapOfInteger& IDsToExclude, |
74 | const Standard_Boolean IsElement, |
75 | const Standard_Integer DisplayMode) const |
76 | { |
77 | Handle (MeshVS_DataSource) aSource = GetDataSource(); |
78 | Handle (MeshVS_Drawer) aDrawer = GetDrawer(); |
79 | |
80 | if ( aSource.IsNull() || aDrawer.IsNull() ) |
81 | return; |
82 | |
83 | Standard_Integer aMaxFaceNodes; |
84 | if ( !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) && aMaxFaceNodes<=0 ) |
85 | return; |
86 | |
87 | MeshVS_DataMapOfIntegerColor* anElemColorMap = (MeshVS_DataMapOfIntegerColor*) &myElemColorMap1; |
88 | MeshVS_DataMapOfIntegerTwoColors* anElemTwoColorsMap = (MeshVS_DataMapOfIntegerTwoColors*)&myElemColorMap2; |
89 | |
90 | MeshVS_DataMapOfColorMapOfInteger aColorsOfElements; |
91 | MeshVS_DataMapOfTwoColorsMapOfInteger aTwoColorsOfElements; |
92 | |
93 | MeshVS_Buffer aCoordsBuf (3*aMaxFaceNodes*sizeof(Standard_Real)); |
94 | TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*aMaxFaceNodes); |
95 | Standard_Integer NbNodes; |
96 | MeshVS_EntityType aType; |
97 | |
98 | if ( !( DisplayMode & GetFlags() ) || !IsElement || |
99 | ( myElemColorMap1.IsEmpty() && myElemColorMap2.IsEmpty() ) ) |
100 | return; |
101 | |
102 | // subtract the hidden elements and ids to exclude (to minimise allocated memory) |
103 | TColStd_PackedMapOfInteger anIDs; |
104 | anIDs.Assign( IDs ); |
105 | Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems(); |
106 | if ( !aHiddenElems.IsNull() ) |
107 | anIDs.Subtract( aHiddenElems->Map() ); |
108 | anIDs.Subtract( IDsToExclude ); |
109 | |
110 | // STEP 0: We looking for two colored elements, who has equal two colors and move it |
111 | // to map of elements with one assigned color |
112 | TColStd_ListOfInteger aColorOne; |
113 | for ( MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors anIter ( *anElemTwoColorsMap ); anIter.More(); anIter.Next () ) |
114 | { |
115 | Standard_Integer aKey = anIter.Key (); |
116 | MeshVS_TwoColors aValue = anIter.Value (); |
117 | Quantity_Color aCol1, aCol2; |
118 | ExtractColors ( aValue, aCol1, aCol2 ); |
119 | if ( aCol1 == aCol2 ) |
120 | { |
121 | aColorOne.Append ( aKey ); |
122 | anElemColorMap->Bind ( aKey, aCol1 ); |
123 | } |
124 | } |
125 | |
126 | for ( TColStd_ListIteratorOfListOfInteger aLIter ( aColorOne ); aLIter.More(); aLIter.Next() ) |
127 | anElemTwoColorsMap->UnBind ( aLIter.Value() ); |
128 | |
129 | // The map is to resort itself by colors. |
130 | // STEP 1: We start sorting elements with one assigned color |
131 | for ( MeshVS_DataMapIteratorOfDataMapOfIntegerColor anIterM ( *anElemColorMap ); anIterM.More(); anIterM.Next () ) |
132 | { |
133 | Standard_Integer aMKey = anIterM.Key (); |
134 | // The ID of current element |
135 | Standard_Boolean IsExist = Standard_False; |
136 | for ( MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger anIterC ( aColorsOfElements ); |
137 | anIterC.More() && !IsExist; anIterC.Next () ) |
138 | if ( anIterC.Key()==anIterM.Value() ) |
139 | { |
140 | TColStd_MapOfInteger& aChangeValue = (TColStd_MapOfInteger&) anIterC.Value(); |
141 | aChangeValue.Add ( aMKey ); |
142 | IsExist = Standard_True; |
143 | } |
144 | |
145 | if ( !IsExist ) |
146 | { |
147 | TColStd_MapOfInteger aNewMap; aNewMap.Add ( aMKey ); |
148 | aColorsOfElements.Bind ( anIterM.Value(), aNewMap ); |
149 | } |
150 | } |
151 | |
152 | // STEP 2: We start sorting elements with two assigned colors |
153 | for ( MeshVS_DataMapIteratorOfDataMapOfIntegerTwoColors anIterM2 ( *anElemTwoColorsMap ); anIterM2.More(); |
154 | anIterM2.Next () ) |
155 | { |
156 | Standard_Integer aMKey = anIterM2.Key (); |
157 | // The ID of current element |
158 | Standard_Boolean IsExist = Standard_False; |
159 | for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger anIterC2 ( aTwoColorsOfElements ); |
160 | anIterC2.More() && !IsExist; anIterC2.Next () ) |
161 | if ( IsEqual ( anIterC2.Key(), anIterM2.Value() ) ) |
162 | { |
163 | TColStd_MapOfInteger& aChangeValue = (TColStd_MapOfInteger&) anIterC2.Value(); |
164 | aChangeValue.Add ( aMKey ); |
165 | IsExist = Standard_True; |
166 | } |
167 | |
168 | if ( !IsExist ) |
169 | { |
170 | TColStd_MapOfInteger aNewMap; aNewMap.Add ( aMKey ); |
171 | aTwoColorsOfElements.Bind ( anIterM2.Value(), aNewMap ); |
172 | } |
173 | } |
174 | |
175 | //Now we are ready to draw faces with equal colors |
7fd59977 |
176 | Aspect_TypeOfLine anEdgeType = Aspect_TOL_SOLID; |
177 | Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID; |
178 | Standard_Integer anEdgeInt, aLineInt; |
179 | Standard_Real anEdgeWidth, aLineWidth; |
180 | Quantity_Color anInteriorColor; |
181 | Quantity_Color anEdgeColor, aLineColor; |
182 | Standard_Boolean anEdgeOn = Standard_True, IsReflect = Standard_False, |
183 | IsMeshSmoothShading = Standard_False; |
184 | |
185 | aDrawer->GetColor ( MeshVS_DA_InteriorColor, anInteriorColor ); |
186 | aDrawer->GetColor ( MeshVS_DA_EdgeColor, anEdgeColor ); |
187 | aDrawer->GetColor ( MeshVS_DA_BeamColor, aLineColor ); |
188 | aDrawer->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth ); |
189 | aDrawer->GetDouble ( MeshVS_DA_BeamWidth, aLineWidth ); |
190 | aDrawer->GetBoolean( MeshVS_DA_ShowEdges, anEdgeOn ); |
191 | aDrawer->GetBoolean( MeshVS_DA_ColorReflection, IsReflect ); |
192 | aDrawer->GetBoolean( MeshVS_DA_SmoothShading, IsMeshSmoothShading ); |
193 | |
7fd59977 |
194 | if ( aDrawer->GetInteger ( MeshVS_DA_EdgeType, anEdgeInt) ) |
195 | anEdgeType = (Aspect_TypeOfLine) anEdgeInt; |
196 | |
197 | if ( aDrawer->GetInteger ( MeshVS_DA_BeamType, aLineInt) ) |
198 | aLineType = (Aspect_TypeOfLine) aLineInt; |
199 | |
200 | Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo; |
201 | Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0; |
202 | TColStd_MapIteratorOfPackedMapOfInteger it (anIDs); |
203 | for( ; it.More(); it.Next() ) |
204 | { |
205 | Standard_Integer aKey = it.Key(); |
206 | if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) ) |
207 | MeshVS_MeshPrsBuilder::HowManyPrimitives |
208 | ( aTopo, Standard_True, Standard_False, NbNodes, |
209 | PolygonVerticesFor3D, PolygonBoundsFor3D ); |
210 | } |
211 | |
212 | Graphic3d_MaterialAspect aMaterial[2]; |
213 | Standard_Integer i; |
214 | for ( i=0; i<2; i++ ) |
215 | { |
216 | // OCC20644 "plastic" is most suitable here, as it is "non-physic" |
217 | // so TelUpdateMaterial() from OpenGl_attri.c uses the interior |
218 | // color from AspectFillArea3d to calculate all material colors |
219 | aMaterial[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC ); |
220 | |
221 | // OCC21720 For single-colored elements turning all material components off is a good idea, |
222 | // as anyhow the normals are not computed and the lighting will be off, |
223 | // the element color will be taken from Graphic3d_AspectFillArea3d's interior color, |
224 | // and there is no need to spend time on updating material properties |
225 | if ( !IsReflect ) |
226 | { |
227 | aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_AMBIENT); |
228 | aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_DIFFUSE); |
229 | aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_SPECULAR); |
230 | aMaterial[i].SetReflectionModeOff(Graphic3d_TOR_EMISSION); |
231 | } |
232 | else |
233 | { |
234 | // OCC20644 This stuff is important in order for elemental and nodal colors |
235 | // to produce similar visual impression and also to make colors match |
236 | // those in the color scale most exactly (the sum of all reflection |
237 | // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder |
238 | // class for more explanations. |
239 | aMaterial[i].SetAmbient( .5 ); |
240 | aMaterial[i].SetDiffuse( .5 ); |
241 | aMaterial[i].SetSpecular( 0. ); |
242 | aMaterial[i].SetEmissive( 0. ); |
243 | } |
244 | } |
245 | |
246 | // Draw elements with one color |
247 | for ( MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger aColIter ( aColorsOfElements ); aColIter.More(); |
248 | aColIter.Next() ) |
249 | { |
250 | Standard_Integer aSize = aColIter.Value().Extent(); |
251 | if ( aSize<=0 ) |
252 | continue; |
253 | |
254 | TColStd_PackedMapOfInteger aCustomElements; |
255 | |
256 | Prs3d_Root::NewGroup ( Prs ); |
257 | Handle ( Graphic3d_Group ) aGGroup = Prs3d_Root::CurrentGroup ( Prs ); |
258 | Prs3d_Root::NewGroup ( Prs ); |
259 | Handle ( Graphic3d_Group ) aLGroup = Prs3d_Root::CurrentGroup ( Prs ); |
260 | |
261 | Handle (Graphic3d_ArrayOfPolygons) aPolyGArr = new Graphic3d_ArrayOfPolygons |
262 | ( aMaxFaceNodes*aSize + PolygonVerticesFor3D, aSize + PolygonBoundsFor3D, 0, IsReflect ); |
263 | Standard_Boolean IsPolyG = Standard_False; |
264 | |
265 | Handle (Graphic3d_ArrayOfPolylines) aPolyLArr = new Graphic3d_ArrayOfPolylines |
266 | ( 2*aSize, aSize ); |
267 | Standard_Boolean IsPolyL = Standard_False; |
268 | |
269 | // OCC20644 NOTE: aColIter.Key() color is then scaled by TelUpdateMaterial() in OpenGl_attri.c |
270 | // using the material reflection coefficients. This affects the visual result. |
271 | Handle(Graphic3d_AspectFillArea3d) anAsp = |
272 | new Graphic3d_AspectFillArea3d ( Aspect_IS_SOLID, aColIter.Key(), anEdgeColor, |
273 | anEdgeType, anEdgeWidth, aMaterial[0], aMaterial[1] ); |
274 | |
275 | Handle(Graphic3d_AspectLine3d) anLAsp = |
276 | new Graphic3d_AspectLine3d ( aColIter.Key(), aLineType, aLineWidth ); |
277 | |
278 | anAsp->SetDistinguishOff (); |
279 | anAsp->SetInteriorColor ( aColIter.Key() ); |
280 | if (anEdgeOn) |
281 | anAsp->SetEdgeOn(); |
282 | else |
283 | anAsp->SetEdgeOff(); |
284 | |
285 | for( it.Reset(); it.More(); it.Next() ) |
286 | { |
287 | Standard_Integer aKey = it.Key(); |
288 | if( aColIter.Value().Contains( aKey ) ) |
289 | { |
290 | if ( !aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) ) |
291 | continue; |
292 | |
293 | if( aType == MeshVS_ET_Face ) |
294 | { |
295 | aPolyGArr->AddBound ( NbNodes ); |
296 | if( IsExcludingOn() ) |
297 | IDsToExclude.Add( aKey ); |
298 | } |
299 | else if( aType == MeshVS_ET_Link ) |
300 | { |
301 | aPolyLArr->AddBound ( NbNodes ); |
302 | if( IsExcludingOn() ) |
303 | IDsToExclude.Add( aKey ); |
304 | } |
305 | else if( aType == MeshVS_ET_Volume ) |
306 | { |
307 | if( IsExcludingOn() ) |
308 | IDsToExclude.Add( aKey ); |
309 | if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) ) |
310 | { |
311 | MeshVS_MeshPrsBuilder::AddVolumePrs( aTopo, aCoords, NbNodes, aPolyGArr, IsReflect, Standard_False, Standard_False, 1.0 ); |
312 | IsPolyG = Standard_True; |
313 | } |
314 | else |
315 | continue; |
316 | } |
317 | else |
318 | { |
319 | aCustomElements.Add( aKey ); |
320 | continue; |
321 | } |
322 | |
323 | // Preparing normal(s) to show reflections if requested |
324 | Handle(TColStd_HArray1OfReal) aNormals; |
325 | Standard_Boolean hasNormals = IsReflect && aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals ); |
326 | |
327 | // Adding vertices (with normals if necessary) |
328 | for ( i=1; i<=NbNodes; i++ ) |
329 | if ( aType == MeshVS_ET_Face ) |
330 | { |
331 | if ( IsReflect ) |
332 | { |
333 | hasNormals ? aPolyGArr->AddVertex ( aCoords(3 * i - 2), |
334 | aCoords(3 * i - 1), |
335 | aCoords(3 * i ), |
336 | aNormals->Value(3 * i - 2), |
337 | aNormals->Value(3 * i - 1), |
338 | aNormals->Value(3 * i ) ) : |
339 | aPolyGArr->AddVertex ( aCoords(3 * i - 2), |
340 | aCoords(3 * i - 1), |
341 | aCoords(3 * i ), |
342 | 0., |
343 | 0., |
344 | 1. ); |
345 | } |
346 | else |
347 | aPolyGArr->AddVertex ( aCoords(3 * i - 2), |
348 | aCoords(3 * i - 1), |
349 | aCoords(3 * i ) ); |
350 | IsPolyG = Standard_True; |
351 | } |
352 | else if ( aType == MeshVS_ET_Link ) |
353 | { |
354 | aPolyLArr->AddVertex ( aCoords(3*i-2), aCoords(3*i-1), aCoords(3*i) ); |
355 | IsPolyL = Standard_True; |
356 | } |
357 | } |
358 | } |
359 | |
360 | if ( IsPolyG ) |
361 | { |
362 | aGGroup->SetPrimitivesAspect ( anAsp ); |
7fd59977 |
363 | aGGroup->AddPrimitiveArray ( aPolyGArr ); |
7fd59977 |
364 | } |
365 | if ( IsPolyL ) |
366 | { |
367 | anAsp->SetEdgeOff(); |
368 | aLGroup->SetPrimitivesAspect ( anAsp ); |
369 | aLGroup->SetPrimitivesAspect ( anLAsp ); |
7fd59977 |
370 | aLGroup->AddPrimitiveArray ( aPolyLArr ); |
7fd59977 |
371 | if (anEdgeOn) |
372 | anAsp->SetEdgeOn(); |
373 | else |
374 | anAsp->SetEdgeOff(); |
375 | } |
376 | |
377 | if( !aCustomElements.IsEmpty() ) |
378 | CustomBuild( Prs, aCustomElements, IDsToExclude, DisplayMode ); |
379 | } |
380 | |
381 | Graphic3d_MaterialAspect aMaterial2[2]; |
382 | for ( i=0; i<2; i++ ) |
383 | { |
384 | // OCC20644 "plastic" is most suitable here, as it is "non-physic" |
385 | // so TelUpdateMaterial() from OpenGl_attri.c uses the interior |
386 | // color from AspectFillArea3d to calculate all material colors |
387 | aMaterial2[i] = Graphic3d_MaterialAspect ( Graphic3d_NOM_PLASTIC ); |
388 | |
389 | if ( !IsReflect ) |
390 | { |
391 | // OCC21720 Cannot turn ALL material components off, as such a material |
392 | // would be ignored by TelUpdateMaterial(), but we need it in order |
393 | // to have different materials for front and back sides! |
394 | // Instead, trying to make material color "nondirectional" with |
395 | // only ambient component on. |
396 | aMaterial2[i].SetReflectionModeOn ( Graphic3d_TOR_AMBIENT ); |
397 | aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_DIFFUSE ); |
398 | aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_SPECULAR ); |
399 | aMaterial2[i].SetReflectionModeOff( Graphic3d_TOR_EMISSION ); |
400 | aMaterial2[i].SetAmbient ( 1. ); |
401 | aMaterial2[i].SetDiffuse ( 0. ); |
402 | aMaterial2[i].SetSpecular( 0. ); |
403 | aMaterial2[i].SetEmissive( 0. ); |
404 | } |
405 | else |
406 | { |
407 | // OCC20644 This stuff is important in order for elemental and nodal colors |
408 | // to produce similar visual impression and also to make colors match |
409 | // those in the color scale most exactly (the sum of all reflection |
410 | // coefficients is equal to 1). See also MeshVS_NodalColorPrsBuilder |
411 | // class for more explanations. |
412 | aMaterial2[i].SetAmbient( .5 ); |
413 | aMaterial2[i].SetDiffuse( .5 ); |
414 | aMaterial2[i].SetSpecular( 0. ); |
415 | aMaterial2[i].SetEmissive( 0. ); |
416 | } |
417 | } |
418 | |
419 | // Draw faces with two color |
420 | for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger aColIter2 ( aTwoColorsOfElements ); |
421 | aColIter2.More(); aColIter2.Next() ) |
422 | { |
423 | Prs3d_Root::NewGroup ( Prs ); |
424 | Handle ( Graphic3d_Group ) aGroup2 = Prs3d_Root::CurrentGroup ( Prs ); |
425 | |
426 | Standard_Integer aSize = aColIter2.Value().Extent(); |
427 | if ( aSize<=0 ) |
428 | continue; |
429 | |
7fd59977 |
430 | Handle (Graphic3d_ArrayOfPolygons) aPolyArr = new Graphic3d_ArrayOfPolygons |
431 | ( aMaxFaceNodes*aSize, aSize, 0, IsReflect ); |
7fd59977 |
432 | |
433 | MeshVS_TwoColors aTC = aColIter2.Key(); |
434 | Quantity_Color aMyIntColor, aMyBackColor; |
435 | ExtractColors ( aTC, aMyIntColor, aMyBackColor ); |
436 | |
437 | // OCC20644 NOTE: aMyIntColor color is then scaled by TelUpdateMaterial() in OpenGl_attri.c |
438 | // using the material reflection coefficients. This affects the visual result. |
439 | Handle(Graphic3d_AspectFillArea3d) anAsp = |
440 | new Graphic3d_AspectFillArea3d ( Aspect_IS_SOLID, aMyIntColor, anEdgeColor, |
441 | anEdgeType, anEdgeWidth, aMaterial2[0], aMaterial2[1] ); |
442 | anAsp->SetDistinguishOn (); |
443 | anAsp->SetInteriorColor ( aMyIntColor ); |
444 | anAsp->SetBackInteriorColor ( aMyBackColor ); |
445 | if (anEdgeOn) |
446 | anAsp->SetEdgeOn(); |
447 | else |
448 | anAsp->SetEdgeOff(); |
449 | |
450 | aGroup2->SetPrimitivesAspect ( anAsp ); |
7fd59977 |
451 | |
452 | for( it.Reset(); it.More(); it.Next() ) |
453 | { |
454 | Standard_Integer aKey = it.Key(); |
455 | if( aColIter2.Value().Contains( aKey ) ) |
456 | { |
457 | if ( !aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) ) |
458 | continue; |
459 | |
460 | if( IsExcludingOn() ) |
461 | IDsToExclude.Add( aKey ); |
462 | |
463 | if ( aType == MeshVS_ET_Face && NbNodes > 0 ) |
464 | { |
465 | // Preparing normal(s) to show reflections if requested |
466 | Handle(TColStd_HArray1OfReal) aNormals; |
467 | // OCC21720 Always passing normals to OpenGL to make materials work |
468 | // For OpenGL: "No normals" -> "No lighting" -> "no materials taken into account" |
469 | Standard_Boolean hasNormals = /*IsReflect &&*/ |
470 | aSource->GetNormalsByElement( aKey, IsMeshSmoothShading, aMaxFaceNodes, aNormals ); |
471 | |
7fd59977 |
472 | aPolyArr->AddBound ( NbNodes ); |
7fd59977 |
473 | |
474 | for ( i=1; i<=NbNodes; i++ ) |
475 | { |
7fd59977 |
476 | if ( IsReflect ) |
477 | { |
478 | hasNormals ? aPolyArr->AddVertex ( aCoords(3 * i - 2), |
479 | aCoords(3 * i - 1), |
480 | aCoords(3 * i ), |
481 | aNormals->Value(3 * i - 2), |
482 | aNormals->Value(3 * i - 1), |
483 | aNormals->Value(3 * i ) ) : |
484 | aPolyArr->AddVertex ( aCoords(3 * i - 2), |
485 | aCoords(3 * i - 1), |
486 | aCoords(3 * i ), |
487 | 0., |
488 | 0., |
489 | 1. ); |
490 | } |
491 | else |
492 | aPolyArr->AddVertex ( aCoords(3*i-2), |
493 | aCoords(3*i-1), |
494 | aCoords(3*i ) ); |
7fd59977 |
495 | } |
7fd59977 |
496 | } |
497 | } |
498 | } |
7fd59977 |
499 | aGroup2->AddPrimitiveArray ( aPolyArr ); |
7fd59977 |
500 | } |
501 | } |
502 | |
503 | //================================================================ |
504 | // Function : SetColors |
505 | // Purpose : |
506 | //================================================================ |
507 | void MeshVS_ElementalColorPrsBuilder::SetColors1 ( const MeshVS_DataMapOfIntegerColor& theColorMap ) |
508 | { |
509 | myElemColorMap1 = theColorMap; |
510 | } |
511 | |
512 | //================================================================ |
513 | // Function : GetColors |
514 | // Purpose : |
515 | //================================================================ |
516 | const MeshVS_DataMapOfIntegerColor& MeshVS_ElementalColorPrsBuilder::GetColors1 () const |
517 | { |
518 | return myElemColorMap1; |
519 | } |
520 | |
521 | //================================================================ |
522 | // Function : HasColors1 |
523 | // Purpose : |
524 | //================================================================ |
525 | Standard_Boolean MeshVS_ElementalColorPrsBuilder::HasColors1 () const |
526 | { |
527 | return ( myElemColorMap1.Extent() >0 ); |
528 | } |
529 | |
530 | //================================================================ |
531 | // Function : GetColor1 |
532 | // Purpose : |
533 | //================================================================ |
534 | Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor1 ( const Standard_Integer ID, |
535 | Quantity_Color& theColor ) const |
536 | { |
537 | Standard_Boolean aRes = myElemColorMap1.IsBound ( ID ); |
538 | if ( aRes ) |
539 | theColor = myElemColorMap1.Find ( ID ); |
540 | |
541 | return aRes; |
542 | } |
543 | |
544 | //================================================================ |
545 | // Function : SetColor1 |
546 | // Purpose : |
547 | //================================================================ |
548 | void MeshVS_ElementalColorPrsBuilder::SetColor1 ( const Standard_Integer theID, |
549 | const Quantity_Color& theCol ) |
550 | { |
551 | Standard_Boolean aRes = myElemColorMap1.IsBound ( theID ); |
552 | if ( aRes ) |
553 | myElemColorMap1.ChangeFind ( theID ) = theCol; |
554 | else |
555 | myElemColorMap1.Bind ( theID, theCol ); |
556 | } |
557 | |
558 | //================================================================ |
559 | // Function : SetColors2 |
560 | // Purpose : |
561 | //================================================================ |
562 | void MeshVS_ElementalColorPrsBuilder::SetColors2 ( const MeshVS_DataMapOfIntegerTwoColors& theColorMap ) |
563 | { |
564 | myElemColorMap2 = theColorMap; |
565 | } |
566 | |
567 | //================================================================ |
568 | // Function : GetColors2 |
569 | // Purpose : |
570 | //================================================================ |
571 | const MeshVS_DataMapOfIntegerTwoColors& MeshVS_ElementalColorPrsBuilder::GetColors2 () const |
572 | { |
573 | return myElemColorMap2; |
574 | } |
575 | |
576 | //================================================================ |
577 | // Function : HasColors2 |
578 | // Purpose : |
579 | //================================================================ |
580 | Standard_Boolean MeshVS_ElementalColorPrsBuilder::HasColors2 () const |
581 | { |
582 | return (myElemColorMap2.Extent()>0); |
583 | } |
584 | |
585 | //================================================================ |
586 | // Function : GetColor2 |
587 | // Purpose : |
588 | //================================================================ |
589 | Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor2 ( const Standard_Integer ID, |
590 | MeshVS_TwoColors& theColor ) const |
591 | { |
592 | Standard_Boolean aRes = myElemColorMap2.IsBound ( ID ); |
593 | if ( aRes ) |
594 | theColor = myElemColorMap2.Find ( ID ); |
595 | |
596 | return aRes; |
597 | } |
598 | |
599 | //================================================================ |
600 | // Function : GetColor2 |
601 | // Purpose : |
602 | //================================================================ |
603 | Standard_Boolean MeshVS_ElementalColorPrsBuilder::GetColor2 ( const Standard_Integer ID, |
604 | Quantity_Color& theColor1, |
605 | Quantity_Color& theColor2 ) const |
606 | { |
607 | MeshVS_TwoColors aTC; |
608 | Standard_Boolean aRes = GetColor2 ( ID, aTC ); |
609 | if ( aRes) |
610 | ExtractColors ( aTC, theColor1, theColor2 ); |
611 | return aRes; |
612 | } |
613 | |
614 | //================================================================ |
615 | // Function : SetColor2 |
616 | // Purpose : |
617 | //================================================================ |
618 | void MeshVS_ElementalColorPrsBuilder::SetColor2 ( const Standard_Integer theID, |
619 | const Quantity_Color& theCol1, |
620 | const Quantity_Color& theCol2 ) |
621 | { |
622 | SetColor2 ( theID, BindTwoColors ( theCol1, theCol2 ) ); |
623 | } |
624 | |
625 | //================================================================ |
626 | // Function : SetColor2 |
627 | // Purpose : |
628 | //================================================================ |
629 | void MeshVS_ElementalColorPrsBuilder::SetColor2 ( const Standard_Integer theID, |
630 | const MeshVS_TwoColors& theCol ) |
631 | { |
632 | Standard_Boolean aRes = myElemColorMap2.IsBound ( theID ); |
633 | if ( aRes ) |
634 | myElemColorMap2.ChangeFind ( theID ) = theCol; |
635 | else |
636 | myElemColorMap2.Bind ( theID, theCol ); |
637 | } |