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