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