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