0031462: Modeling Algorithms - BOP result depends on the arguments order
[occt.git] / src / MeshVS / MeshVS_MeshPrsBuilder.cxx
CommitLineData
b311480e 1// Created on: 2003-09-16
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
42cf5bc1 17#include <Aspect_InteriorStyle.hxx>
a577aaab 18#include <Graphic3d_ArrayOfPoints.hxx>
42cf5bc1 19#include <Graphic3d_ArrayOfPolygons.hxx>
7fd59977 20#include <Graphic3d_ArrayOfPolylines.hxx>
42cf5bc1 21#include <Graphic3d_ArrayOfPrimitives.hxx>
22#include <Graphic3d_ArrayOfSegments.hxx>
23#include <Graphic3d_ArrayOfTriangles.hxx>
24#include <Graphic3d_AspectFillArea3d.hxx>
25#include <Graphic3d_AspectLine3d.hxx>
26#include <Graphic3d_AspectMarker3d.hxx>
7fd59977 27#include <Graphic3d_Group.hxx>
42cf5bc1 28#include <MeshVS_Buffer.hxx>
7fd59977 29#include <MeshVS_DataSource.hxx>
30#include <MeshVS_Drawer.hxx>
7fd59977 31#include <MeshVS_DrawerAttribute.hxx>
32#include <MeshVS_MapOfTwoNodes.hxx>
42cf5bc1 33#include <MeshVS_Mesh.hxx>
34#include <MeshVS_MeshPrsBuilder.hxx>
37ac4a67 35#include <MeshVS_SymmetricPairHasher.hxx>
42cf5bc1 36#include <MeshVS_Tool.hxx>
37ac4a67 37#include <NCollection_Map.hxx>
38#include <NCollection_Vector.hxx>
42cf5bc1 39#include <Prs3d_LineAspect.hxx>
40#include <Prs3d_PointAspect.hxx>
41#include <Prs3d_Presentation.hxx>
42#include <Prs3d_Root.hxx>
43#include <Prs3d_ShadingAspect.hxx>
44#include <Quantity_NameOfColor.hxx>
45#include <Select3D_SensitivePoint.hxx>
46#include <Standard_Type.hxx>
47#include <TColStd_Array1OfInteger.hxx>
48#include <TColStd_Array1OfReal.hxx>
49#include <TColStd_HPackedMapOfInteger.hxx>
50#include <TColStd_ListIteratorOfListOfReal.hxx>
51#include <TColStd_MapIntegerHasher.hxx>
52#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
53#include <TColStd_MapOfInteger.hxx>
54#include <TColStd_PackedMapOfInteger.hxx>
55#include <TColStd_SequenceOfInteger.hxx>
7fd59977 56
7c65581d 57#ifdef _WIN32
58 #include <malloc.h> // for alloca()
59#endif
60
92efcf78 61IMPLEMENT_STANDARD_RTTIEXT(MeshVS_MeshPrsBuilder,MeshVS_PrsBuilder)
62
7fd59977 63//================================================================
64// Function : Constructor MeshVS_MeshPrsBuilder
65// Purpose :
66//================================================================
67MeshVS_MeshPrsBuilder::MeshVS_MeshPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
68 const Standard_Integer& DisplayModeMask,
69 const Handle (MeshVS_DataSource)& DS,
70 const Standard_Integer Id,
71 const MeshVS_BuilderPriority& Priority )
72: MeshVS_PrsBuilder ( Parent, DisplayModeMask, DS, Id, Priority )
73{
74}
75
76//================================================================
77// Function : Build
78// Purpose :
79//================================================================
80void MeshVS_MeshPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
81 const TColStd_PackedMapOfInteger& IDs,
82 TColStd_PackedMapOfInteger& IDsToExclude,
83 const Standard_Boolean IsElement,
84 const Standard_Integer DisplayMode ) const
85{
86 if ( DisplayMode <= 0 )
87 return;
88
89 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
90 Standard_Integer Extent = IDs.Extent();
91
92 if ( HasHilightFlag && Extent == 1)
93 BuildHilightPrs ( Prs, IDs, IsElement );
94 else if ( IsElement )
95 BuildElements ( Prs, IDs, IDsToExclude, DisplayMode );
96 else
97 BuildNodes ( Prs, IDs, IDsToExclude, DisplayMode );
98}
99
100//================================================================
101// Function : BuildNodes
102// Purpose :
103//================================================================
104void MeshVS_MeshPrsBuilder::BuildNodes ( const Handle(Prs3d_Presentation)& Prs,
105 const TColStd_PackedMapOfInteger& IDs,
106 TColStd_PackedMapOfInteger& IDsToExclude,
107 const Standard_Integer DisplayMode ) const
108{
109 Handle( MeshVS_DataSource ) aSource = GetDataSource();
110 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
111 Handle (Graphic3d_AspectMarker3d) aNodeMark =
112 MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
113 if ( aSource.IsNull() || aDrawer.IsNull() || aNodeMark.IsNull() )
114 return;
115
116 Standard_Boolean DisplayFreeNodes = Standard_True;
117 aDrawer->GetBoolean( MeshVS_DA_DisplayNodes, DisplayFreeNodes );
118 Standard_Boolean HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 );
119 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
120
121 Standard_Real aCoordsBuf[ 3 ];
122 TColStd_Array1OfReal aCoords( *aCoordsBuf, 1, 3 );
123 Standard_Integer NbNodes;
124 MeshVS_EntityType aType;
125
126 if ( !DisplayFreeNodes )
127 return;
128
129 TColStd_PackedMapOfInteger anIDs;
130 anIDs.Assign( IDs );
131 if ( !HasSelectFlag && !HasHilightFlag )
132 {
37ac4a67 133 // subtract the hidden nodes and ids to exclude (to minimize allocated memory)
7fd59977 134 Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = myParentMesh->GetHiddenNodes();
135 if ( !aHiddenNodes.IsNull() )
136 anIDs.Subtract( aHiddenNodes->Map() );
137 }
138 anIDs.Subtract( IDsToExclude );
139
140 Standard_Integer upper = anIDs.Extent();
141 if ( upper<=0 )
142 return;
143
a577aaab 144 Handle(Graphic3d_ArrayOfPoints) aNodePoints = new Graphic3d_ArrayOfPoints (upper);
7fd59977 145 Standard_Integer k=0;
146 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
147 for( ; it.More(); it.Next() )
148 {
149 Standard_Integer aKey = it.Key();
150 if ( aSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) )
151 {
152 if ( IsExcludingOn() )
153 IDsToExclude.Add (aKey);
a577aaab 154 k++;
155 aNodePoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
7fd59977 156 }
157 }
158
159 if ( k>0 )
160 {
161 Prs3d_Root::NewGroup ( Prs );
162 Handle (Graphic3d_Group) aNodeGroup = Prs3d_Root::CurrentGroup ( Prs );
163 aNodeGroup->SetPrimitivesAspect ( aNodeMark );
a577aaab 164 aNodeGroup->AddPrimitiveArray (aNodePoints);
7fd59977 165 }
166}
167
168//================================================================
169// Function : BuildElements
170// Purpose :
171//================================================================
172void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs,
173 const TColStd_PackedMapOfInteger& IDs,
174 TColStd_PackedMapOfInteger& IDsToExclude,
175 const Standard_Integer DisplayMode ) const
176{
37ac4a67 177 Standard_Integer maxnodes;
7fd59977 178
37ac4a67 179 Handle(MeshVS_DataSource) aSource = GetDataSource();
7fd59977 180 if ( aSource.IsNull() )
181 return;
182
183 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
184 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
185 maxnodes <= 0 )
186 return;
187
188 //----------- extract useful display mode flags ----------
189 Standard_Integer aDispMode = ( DisplayMode & GetFlags() );
190 if ( ( aDispMode & MeshVS_DMF_DeformedMask) != 0 )
191 {
192 aDispMode /= MeshVS_DMF_DeformedPrsWireFrame;
193 // This transformation turns deformed mesh flags to real display modes
194 }
195 aDispMode &= MeshVS_DMF_OCCMask;
196 //--------------------------------------------------------
197
b1492cb3 198 Standard_Real aShrinkCoef = 0.0;
7fd59977 199 aDrawer->GetDouble ( MeshVS_DA_ShrinkCoeff, aShrinkCoef );
200
201 Standard_Boolean IsWireFrame = ( aDispMode==MeshVS_DMF_WireFrame ),
202 IsShading = ( aDispMode==MeshVS_DMF_Shading ),
203 IsShrink = ( aDispMode==MeshVS_DMF_Shrink ),
204 HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 ),
205 HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 ),
b1492cb3 206 IsMeshReflect = Standard_False, IsMeshAllowOverlap = Standard_False,
207 IsMeshSmoothShading = Standard_False;
7fd59977 208
209 aDrawer->GetBoolean ( MeshVS_DA_Reflection, IsMeshReflect );
210 aDrawer->GetBoolean ( MeshVS_DA_IsAllowOverlapped, IsMeshAllowOverlap );
b1492cb3 211 const Standard_Boolean IsReflect = ( IsMeshReflect && !HasHilightFlag );
7fd59977 212 aDrawer->GetBoolean ( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
213
37ac4a67 214 // display mode for highlighted prs of groups
7fd59977 215 IsShrink = ( IsShrink && !HasHilightFlag );
216 IsShading = ( IsShading || HasHilightFlag );
217
218 //---------- Creating AspectFillArea3d and AspectLine3d -------------
219 Graphic3d_MaterialAspect AMat;
220 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
221 if ( !IsReflect )
222 {
61168418 223 AMat.SetAmbientColor (Quantity_NOC_BLACK);
224 AMat.SetDiffuseColor (Quantity_NOC_BLACK);
225 AMat.SetSpecularColor(Quantity_NOC_BLACK);
226 AMat.SetEmissiveColor(Quantity_NOC_BLACK);
7fd59977 227 }
228 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
229 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d ( GetDrawer() );
230 //-------------------------------------------------------------------
231
232 Standard_Boolean IsOverlapControl =
233 !IsMeshAllowOverlap && ( IsWireFrame || IsShading ) && !HasSelectFlag;
234
37ac4a67 235 // subtract the hidden elements and ids to exclude (to minimize allocated memory)
7fd59977 236 TColStd_PackedMapOfInteger anIDs;
237 anIDs.Assign( IDs );
238 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
239 if ( !aHiddenElems.IsNull() )
240 anIDs.Subtract( aHiddenElems->Map() );
241 anIDs.Subtract( IDsToExclude );
242
243 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
244 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
37ac4a67 245
246 Standard_Boolean showEdges = Standard_True;
247 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges );
248
249 showEdges = IsWireFrame || showEdges;
250
251 Standard_Integer* aNodesBuf = (Standard_Integer*) alloca (maxnodes * sizeof (Standard_Integer));
252 Standard_Real* aCoordsBuf = (Standard_Real*) alloca (3 * maxnodes * sizeof (Standard_Real));
253
254 TColStd_Array1OfInteger aNodes (*aNodesBuf, 1, maxnodes);
255 TColStd_Array1OfReal aCoords (*aCoordsBuf, 1, 3 * maxnodes);
256
257 Standard_Integer aNbFacePrimitives = 0;
258 Standard_Integer aNbVolmPrimitives = 0;
259 Standard_Integer aNbEdgePrimitives = 0;
260 Standard_Integer aNbLinkPrimitives = 0;
261
262 MeshVS_EntityType aType;
263
264 for (it.Reset(); it.More(); it.Next())
7fd59977 265 {
37ac4a67 266 Standard_Integer aNbNodes = 0;
267
268 if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType))
269 continue;
270
271 if (aType == MeshVS_ET_Volume)
7fd59977 272 {
37ac4a67 273 if (aSource->Get3DGeom (it.Key(), aNbNodes, aTopo))
274 {
275 for (Standard_Integer aFaceIdx = aTopo->Lower(); aFaceIdx <= aTopo->Upper(); ++aFaceIdx)
276 {
277 const TColStd_SequenceOfInteger& aFaceNodes = aTopo->Value (aFaceIdx);
278
279 if (showEdges) // add edge segments
280 {
281 aNbEdgePrimitives += aFaceNodes.Length();
282 }
283
284 if (IsShading || IsShrink) // add volumetric cell triangles
285 {
286 if (!HasSelectFlag)
287 aNbVolmPrimitives += aFaceNodes.Length() - 2;
288 }
289 }
290 }
291 }
292 else if (aType == MeshVS_ET_Link)
293 {
294 if (showEdges)
295 {
296 aNbLinkPrimitives += 1; // add link segment
297 }
298 }
299 else if (aType == MeshVS_ET_Face)
300 {
301 if (showEdges)
302 {
303 aNbEdgePrimitives += aNbNodes; // add edge segments
304 }
305
306 if (!IsOverlapControl || IsShading)
307 {
308 if ((IsShading || IsShrink) && !HasSelectFlag)
309 {
310 aNbFacePrimitives += aNbNodes - 2; // add face triangles
311 }
312 }
7fd59977 313 }
314 }
315
37ac4a67 316 // Here we do not use indices arrays because they are not effective for some mesh
317 // drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
318 // cell rendering (normal interpolation is not always applicable - flat shading),
319 // elemental coloring (color interpolation is impossible)
320 Handle (Graphic3d_ArrayOfTriangles) aVolmTriangles =
321 new Graphic3d_ArrayOfTriangles (aNbVolmPrimitives * 3, 0, IsReflect);
322 Handle (Graphic3d_ArrayOfTriangles) aFaceTriangles =
323 new Graphic3d_ArrayOfTriangles (aNbFacePrimitives * 3, 0, IsReflect);
7fd59977 324
37ac4a67 325 Handle (Graphic3d_ArrayOfSegments) aLinkSegments;
326 Handle (Graphic3d_ArrayOfSegments) aEdgeSegments;
327
328 if (showEdges)
7fd59977 329 {
37ac4a67 330 aLinkSegments = new Graphic3d_ArrayOfSegments (aNbLinkPrimitives * 2);
331 aEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2);
7fd59977 332 }
333
7fd59977 334 TColStd_PackedMapOfInteger aCustomElements;
335
b6472664 336 Quantity_Color anOldEdgeColor;
337 Quantity_Color anEdgeColor = aFill->EdgeColor();
7fd59977 338 MeshVS_MapOfTwoNodes aLinkNodes;
37ac4a67 339
340 // Forbid drawings of edges which overlap with some links
341 if (showEdges && IsOverlapControl)
342 {
343 for (it.Reset(); it.More(); it.Next())
7fd59977 344 {
37ac4a67 345 if (aSource->GetGeomType (it.Key(), Standard_True, aType) && aType == MeshVS_ET_Link)
7fd59977 346 {
37ac4a67 347 Standard_Integer aNbNodes;
348
349 if (aSource->GetNodesByElement (it.Key(), aNodes, aNbNodes) && aNbNodes == 2)
7fd59977 350 {
37ac4a67 351 aLinkNodes.Add (MeshVS_TwoNodes (aNodes(1), aNodes(2)));
7fd59977 352 }
353 }
354 }
37ac4a67 355 }
356
357 NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aSegmentMap;
7fd59977 358
37ac4a67 359 for (it.Reset(); it.More(); it.Next())
7fd59977 360 {
37ac4a67 361 const Standard_Integer aKey = it.Key();
362
363 Standard_Integer NbNodes;
364 if (!aSource->GetGeom (aKey, Standard_True, aCoords, NbNodes, aType))
365 continue;
7fd59977 366
37ac4a67 367 if (!aSource->GetNodesByElement (aKey, aNodes, NbNodes))
7fd59977 368 continue;
369
37ac4a67 370 switch (aType)
7fd59977 371 {
37ac4a67 372 case MeshVS_ET_Volume:
373 {
374 if (IsExcludingOn())
7fd59977 375 IDsToExclude.Add (aKey);
37ac4a67 376
377 if (aSource->Get3DGeom (aKey, NbNodes, aTopo))
7fd59977 378 {
37ac4a67 379 // Add wire-frame presentation (draw edges for shading mode as well)
380 if (showEdges)
381 {
382 AddVolumePrs (aTopo, aCoords, NbNodes,
383 aEdgeSegments, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
384 }
385
386 // Add shading presentation
387 if ((IsShading || IsShrink) && !HasSelectFlag)
388 {
389 AddVolumePrs (aTopo, aCoords, NbNodes,
390 aVolmTriangles, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef);
391 }
7fd59977 392 }
37ac4a67 393 }
394 break;
7fd59977 395
37ac4a67 396 case MeshVS_ET_Link:
397 {
398 if (IsExcludingOn())
7fd59977 399 IDsToExclude.Add (aKey);
7fd59977 400
37ac4a67 401 if (showEdges)
7fd59977 402 {
37ac4a67 403 AddLinkPrs (aCoords, aLinkSegments, IsShrink || HasSelectFlag, aShrinkCoef);
404 }
405 }
406 break;
7fd59977 407
37ac4a67 408 case MeshVS_ET_Face:
409 {
410 if (IsExcludingOn())
411 IDsToExclude.Add (aKey);
412
413 if (showEdges && IsOverlapControl)
414 {
7fd59977 415 Standard_Integer Last = 0;
37ac4a67 416
417 MeshVS_TwoNodes aTwoNodes (aNodes (1));
418
419 for (Standard_Integer i = 1; i <= NbNodes; ++i)
7fd59977 420 {
37ac4a67 421 if (i > 1)
7fd59977 422 aTwoNodes.First = aTwoNodes.Second;
423
37ac4a67 424 aTwoNodes.Second = (i < NbNodes) ? aNodes (i+1) : aNodes (1);
425
426 if (aLinkNodes.Contains (aTwoNodes))
427 {
428 for (Standard_Integer aNodeIdx = Last + 1; aNodeIdx < i; ++aNodeIdx)
7fd59977 429 {
37ac4a67 430 const Standard_Integer aNextIdx = aNodeIdx + 1;
431
432 aEdgeSegments->AddVertex (
433 aCoords (3 * aNodeIdx - 2), aCoords (3 * aNodeIdx - 1), aCoords (3 * aNodeIdx));
434 aEdgeSegments->AddVertex (
435 aCoords (3 * aNextIdx - 2), aCoords (3 * aNextIdx - 1), aCoords (3 * aNextIdx));
7fd59977 436 }
37ac4a67 437
438 Last = i;
439 }
7fd59977 440 }
37ac4a67 441
442 if (NbNodes - Last > 0)
7fd59977 443 {
37ac4a67 444 for (Standard_Integer aNodeIdx = Last; aNodeIdx < NbNodes; ++aNodeIdx)
445 {
446 const Standard_Integer aNextIdx = (aNodeIdx + 1) % NbNodes;
447
448 const MeshVS_NodePair aSegment (aNodes (aNodeIdx + 1),
449 aNodes (aNextIdx + 1));
450
451 if (!aSegmentMap.Contains (aSegment))
452 {
453 aEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
454 aCoords (3 * aNodeIdx + 2),
455 aCoords (3 * aNodeIdx + 3));
7fd59977 456
37ac4a67 457 aEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
458 aCoords (3 * aNextIdx + 2),
459 aCoords (3 * aNextIdx + 3));
460
461 aSegmentMap.Add (aSegment);
462 }
463 }
7fd59977 464 }
465 }
466
37ac4a67 467 if (!IsOverlapControl || IsShading)
7fd59977 468 {
37ac4a67 469 if (!IsOverlapControl && showEdges)
470 {
471 AddFaceWirePrs (aCoords, NbNodes,
472 aEdgeSegments, IsShrink || HasSelectFlag, aShrinkCoef);
473 }
474
475 if ((IsShading || IsShrink) && !HasSelectFlag)
476 {
477 AddFaceSolidPrs (aKey, aCoords, NbNodes, maxnodes, aFaceTriangles, IsReflect,
478 IsShrink || HasSelectFlag, aShrinkCoef, IsMeshSmoothShading);
479 }
7fd59977 480 }
37ac4a67 481 }
482 break;
7fd59977 483
484 default:
37ac4a67 485 {
486 aCustomElements.Add (aKey);
487 }
7fd59977 488 }
489 }
490
37ac4a67 491 if (IsShrink)
7fd59977 492 {
493 anOldEdgeColor = anEdgeColor;
37ac4a67 494 aFill->SetEdgeColor (Quantity_NOC_BLACK);
7fd59977 495 }
496
37ac4a67 497 //std::cout << "Actual extents: " << std::endl
498 // << "Face tris: " << aFaceTriangles->ItemNumber() << " from " << aNbFacePrimitives << std::endl
499 // << "Volm tris: " << aVolmTriangles->ItemNumber() << " from " << aNbVolmPrimitives << std::endl
500 // << "Face segs: " << aEdgeSegments->ItemNumber() << " from " << aNbEdgePrimitives << std::endl
501 // << "Link segs: " << aLinkSegments->ItemNumber() << " from " << aNbLinkPrimitives << std::endl;
502
503 DrawArrays ( Prs, aFaceTriangles, aEdgeSegments, aLinkSegments, aVolmTriangles,
7fd59977 504 !showEdges, HasSelectFlag, aFill, aBeam );
505
506 if ( !aCustomElements.IsEmpty() )
507 CustomBuild ( Prs, aCustomElements, IDsToExclude, DisplayMode );
508
509 if( IsShrink )
510 aFill->SetEdgeColor( anOldEdgeColor );
511}
512
513//================================================================
514// Function : BuildHilightPrs
515// Purpose :
516//================================================================
517void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)& Prs,
518 const TColStd_PackedMapOfInteger& IDs,
519 const Standard_Boolean IsElement ) const
520{
521 Standard_Integer maxnodes;
522
523 Handle (MeshVS_DataSource) aSource = GetDataSource();
524 if ( aSource.IsNull() || IDs.IsEmpty() )
525 return;
526
527 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
528 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
529 maxnodes <= 0 )
530 return;
531
532 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
533 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*maxnodes);
534
535 Graphic3d_MaterialAspect AMat;
536 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
61168418 537 AMat.SetAmbientColor (Quantity_NOC_BLACK);
538 AMat.SetDiffuseColor (Quantity_NOC_BLACK);
539 AMat.SetSpecularColor(Quantity_NOC_BLACK);
540 AMat.SetEmissiveColor(Quantity_NOC_BLACK);
7fd59977 541
542 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
543 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d( GetDrawer() );
544 Handle( Graphic3d_AspectMarker3d ) aNodeMark = MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
545
546 // Hilight one element or node
547 TColStd_MapIteratorOfPackedMapOfInteger it (IDs);
548 Standard_Integer ID = it.Key(), NbNodes;
549 MeshVS_EntityType aType;
550
551 if ( !aSource->GetGeom ( ID, IsElement, aCoords, NbNodes, aType ) )
552 return;
553
554 Prs3d_Root::NewGroup ( Prs );
555 Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup ( Prs );
556
557 switch ( aType )
558 {
559 case MeshVS_ET_Node :
560 {
a577aaab 561 aHilightGroup->SetPrimitivesAspect (aNodeMark);
562 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
563 anArrayOfPoints->AddVertex (aCoords(1), aCoords(2), aCoords(3));
564 aHilightGroup->AddPrimitiveArray (anArrayOfPoints);
7fd59977 565 }
566 break;
567
568 case MeshVS_ET_Link:
569 {
570 aHilightGroup->SetPrimitivesAspect ( aBeam );
b8ddfc2f 571 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
572 aPrims->AddVertex(aCoords(1),aCoords(2),aCoords(3));
573 aPrims->AddVertex(aCoords(4),aCoords(5),aCoords(6));
574 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 575 }
576 break;
577
578 case MeshVS_ET_Face:
579 if ( NbNodes > 0 )
580 {
7fd59977 581 aHilightGroup->SetPrimitivesAspect ( aFill );
b8ddfc2f 582 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(NbNodes);
7fd59977 583 for ( Standard_Integer k=1; k<=NbNodes; k++)
b8ddfc2f 584 aPrims->AddVertex(aCoords(3*k-2),aCoords(3*k-1),aCoords(3*k));
585 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 586 }
587 break;
588
589 case MeshVS_ET_Volume:
590 if( NbNodes > 0 )
591 {
592 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
593
594 aHilightGroup->SetPrimitivesAspect ( aFill );
595
596 if( aSource->Get3DGeom( ID, NbNodes, aTopo ) )
597 {
b8ddfc2f 598 const Standard_Integer up = aTopo->Upper();
599 const Standard_Integer lo = aTopo->Lower();
600 Standard_Integer nbnodes = 0, i, j;
601 for( i=lo; i<=up; i++ )
602 nbnodes += aTopo->Value( i ).Length();
603
604 Handle(Graphic3d_ArrayOfPolygons) aPrims = new Graphic3d_ArrayOfPolygons(nbnodes,aTopo->Length());
605 for( i=lo; i<=up; i++ )
7fd59977 606 {
607 const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i );
b8ddfc2f 608 const Standard_Integer m = aSeq.Length();
609 aPrims->AddBound(m);
7fd59977 610 for( j=1; j<=m; j++ )
611 {
b8ddfc2f 612 const Standard_Integer ind = 3*aSeq.Value( j );
613 aPrims->AddVertex(aCoords(ind+1),aCoords(ind+2),aCoords(ind+3));
7fd59977 614 }
7fd59977 615 }
b8ddfc2f 616 aHilightGroup->AddPrimitiveArray(aPrims);
7fd59977 617 }
618 }
619 break;
620
621 default:
622 {
623 TColStd_PackedMapOfInteger tmp;
624 CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs );
625 }
626 break;
627 }
628}
629
630//================================================================
631// Function : AddLinkPrs
632// Purpose :
633//================================================================
37ac4a67 634void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
635 const Handle(Graphic3d_ArrayOfSegments)& theSegments,
636 const Standard_Boolean theIsShrinked,
637 const Standard_Real theShrinkCoef) const
7fd59977 638{
37ac4a67 639 Standard_Real aX1 = theCoords (1);
640 Standard_Real aY1 = theCoords (2);
641 Standard_Real aZ1 = theCoords (3);
642 Standard_Real aX2 = theCoords (4);
643 Standard_Real aY2 = theCoords (5);
644 Standard_Real aZ2 = theCoords (6);
645
646 if (theIsShrinked)
7fd59977 647 {
37ac4a67 648 const Standard_Real xG = (aX1 + aX2) * 0.5;
649 const Standard_Real yG = (aY1 + aY2) * 0.5;
650 const Standard_Real zG = (aZ1 + aZ2) * 0.5;
651
652 aX1 = (aX1 - xG) * theShrinkCoef + xG;
653 aY1 = (aY1 - yG) * theShrinkCoef + yG;
654 aZ1 = (aZ1 - zG) * theShrinkCoef + zG;
655
656 aX2 = 2.0 * xG - aX1;
657 aY2 = 2.0 * yG - aY1;
658 aZ2 = 2.0 * zG - aZ1;
7fd59977 659 }
37ac4a67 660
661 theSegments->AddVertex (aX1, aY1, aZ1);
662 theSegments->AddVertex (aX2, aY2, aZ2);
7fd59977 663}
664
665//================================================================
666// Function : AddFaceWirePrs
667// Purpose :
668//================================================================
37ac4a67 669void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
670 const Standard_Integer theNbNodes,
671 const Handle(Graphic3d_ArrayOfSegments)& theSegments,
672 const Standard_Boolean theIsShrinked,
673 const Standard_Real theShrinkingCoef) const
7fd59977 674{
37ac4a67 675 Standard_Real aCenterX = 0.0;
676 Standard_Real aCenterY = 0.0;
677 Standard_Real aCenterZ = 0.0;
7fd59977 678
37ac4a67 679 if (theIsShrinked)
7fd59977 680 {
37ac4a67 681 CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
682 }
683
684 NCollection_Vector<gp_XYZ> aNodes (theNbNodes);
685
686 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
687 {
688 gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1),
689 theCoords (3 * aNodeIdx + 2),
690 theCoords (3 * aNodeIdx + 3));
691
692 if (theIsShrinked)
7fd59977 693 {
37ac4a67 694 aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX);
695 aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY);
696 aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ);
7fd59977 697 }
37ac4a67 698
699 aNodes.Append (aPnt);
700 }
701
702 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
703 {
704 theSegments->AddVertex (aNodes.Value (aNodeIdx).X(),
705 aNodes.Value (aNodeIdx).Y(),
706 aNodes.Value (aNodeIdx).Z());
707
708 const Standard_Integer aNextIdx = (aNodeIdx + 1) % theNbNodes;
709
710 theSegments->AddVertex (aNodes.Value (aNextIdx).X(),
711 aNodes.Value (aNextIdx).Y(),
712 aNodes.Value (aNextIdx).Z());
7fd59977 713 }
7fd59977 714}
715
716//================================================================
717// Function : AddFaceSolidPrs
718// Purpose :
719//================================================================
37ac4a67 720void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer theID,
721 const TColStd_Array1OfReal& theCoords,
722 const Standard_Integer theNbNodes,
723 const Standard_Integer theMaxNodes,
724 const Handle(Graphic3d_ArrayOfTriangles)& theTriangles,
725 const Standard_Boolean theIsShaded,
726 const Standard_Boolean theIsShrinked,
727 const Standard_Real theShrinkingCoef,
728 const Standard_Boolean theIsSmoothShading) const
7fd59977 729{
37ac4a67 730 Handle(MeshVS_DataSource) aDataSource = myParentMesh->GetDataSource();
731
732 if (aDataSource.IsNull())
7fd59977 733 return;
734
37ac4a67 735 Standard_Real aCenterX = 0.0;
736 Standard_Real aCenterY = 0.0;
737 Standard_Real aCenterZ = 0.0;
738 Standard_Real aNormalX = 0.0;
739 Standard_Real aNormalY = 0.0;
740 Standard_Real aNormalZ = 0.0;
7fd59977 741
37ac4a67 742 if (theIsShrinked)
743 {
744 CalculateCenter (theCoords, theNbNodes, aCenterX, aCenterY, aCenterZ);
745 }
7fd59977 746
37ac4a67 747 NCollection_Vector<gp_XYZ> aVertexNormals (theMaxNodes);
748
749 if (theIsShaded)
7fd59977 750 {
37ac4a67 751 if (theIsSmoothShading)
752 {
753 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= theNbNodes; ++aNodeIdx)
754 {
755 if (!aDataSource->GetNodeNormal (aNodeIdx, theID, aNormalX, aNormalY, aNormalZ))
756 break;
757
758 aVertexNormals.Append (gp_XYZ (aNormalX, aNormalY, aNormalZ));
759 }
760 }
761
762 if (!theIsSmoothShading || aVertexNormals.Size() != theNbNodes)
763 {
764 aDataSource->GetNormal (theID, theMaxNodes, aNormalX, aNormalY, aNormalZ);
765 }
7fd59977 766 }
767
37ac4a67 768 NCollection_Vector<gp_XYZ> aNodes (theMaxNodes);
769
770 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes; ++aNodeIdx)
7fd59977 771 {
37ac4a67 772 gp_XYZ aPnt (theCoords (3 * aNodeIdx + 1),
773 theCoords (3 * aNodeIdx + 2),
774 theCoords (3 * aNodeIdx + 3));
775
776 if (theIsShrinked)
7fd59977 777 {
37ac4a67 778 aPnt.SetX ((aPnt.X() - aCenterX) * theShrinkingCoef + aCenterX);
779 aPnt.SetY ((aPnt.Y() - aCenterY) * theShrinkingCoef + aCenterY);
780 aPnt.SetZ ((aPnt.Z() - aCenterZ) * theShrinkingCoef + aCenterZ);
7fd59977 781 }
782
37ac4a67 783 aNodes.Append (aPnt);
784 }
785
786 // Triangulate polygon
787 for (Standard_Integer aNodeIdx = 0; aNodeIdx < theNbNodes - 2; ++aNodeIdx)
788 {
789 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx)
7fd59977 790 {
37ac4a67 791 if (theIsShaded)
792 {
793 if (theIsSmoothShading && aVertexNormals.Size() == theNbNodes)
794 {
795 aNormalX = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X();
796 aNormalY = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y();
797 aNormalZ = aVertexNormals.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z();
798 }
799
800 theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(),
801 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(),
802 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z(),
803 aNormalX,
804 aNormalY,
805 aNormalZ);
806 }
807 else
808 {
809 theTriangles->AddVertex (aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).X(),
810 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Y(),
811 aNodes.Value (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)).Z());
812 }
7fd59977 813 }
7fd59977 814 }
815}
816
817//================================================================
818// Function : AddVolumePrs
819// Purpose :
820//================================================================
37ac4a67 821void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo,
822 const TColStd_Array1OfReal& theNodes,
823 const Standard_Integer theNbNodes,
824 const Handle(Graphic3d_ArrayOfPrimitives)& theArray,
825 const Standard_Boolean theIsShaded,
826 const Standard_Boolean theIsShrinked,
827 const Standard_Boolean theIsSelected,
828 const Standard_Real theShrinkCoef)
7fd59977 829{
37ac4a67 830 Standard_Real aCenter[] = { 0.0, 0.0, 0.0 };
7fd59977 831
37ac4a67 832 Standard_Integer aLow = theNodes.Lower();
833
834 if (theTopo.IsNull() || theArray.IsNull())
7fd59977 835 return;
836
37ac4a67 837 if (theIsShrinked)
7fd59977 838 {
37ac4a67 839 for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3 * theNbNodes; ++aNodeIdx)
840 {
841 aCenter[aNodeIdx % 3] += theNodes.Value (aLow + aNodeIdx);
842 }
7fd59977 843
37ac4a67 844 aCenter[0] /= theNbNodes;
845 aCenter[1] /= theNbNodes;
846 aCenter[2] /= theNbNodes;
7fd59977 847 }
848
37ac4a67 849 Standard_Boolean aIsPolygons = theArray->IsKind (STANDARD_TYPE (Graphic3d_ArrayOfTriangles));
7fd59977 850
37ac4a67 851 if (aIsPolygons)
852 {
853 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
7fd59977 854 {
37ac4a67 855 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
856 const Standard_Integer aNbPolyNodes = aFaceNodes.Length();
7fd59977 857
37ac4a67 858 Standard_Real* aPolyNodesBuf = (Standard_Real*) alloca ((3 * aNbPolyNodes + 1) * sizeof (Standard_Real));
859 TColStd_Array1OfReal aPolyNodes (*aPolyNodesBuf, 0, 3 * aNbPolyNodes);
860
861 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes; ++aNodeIdx)
7fd59977 862 {
37ac4a67 863 Standard_Integer anIdx = aFaceNodes.Value (aNodeIdx + 1);
864
865 Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0);
866 Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1);
867 Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2);
868
869 if (theIsShrinked)
870 {
871 aX = aCenter[0] + theShrinkCoef * (aX - aCenter[0]);
872 aY = aCenter[1] + theShrinkCoef * (aY - aCenter[1]);
873 aZ = aCenter[2] + theShrinkCoef * (aZ - aCenter[2]);
7fd59977 874 }
875
37ac4a67 876 aPolyNodes.SetValue (3 * aNodeIdx + 1, aX);
877 aPolyNodes.SetValue (3 * aNodeIdx + 2, aY);
878 aPolyNodes.SetValue (3 * aNodeIdx + 3, aZ);
7fd59977 879 }
37ac4a67 880
881 gp_Vec aNorm;
7fd59977 882
37ac4a67 883 if (theIsShaded)
7fd59977 884 {
37ac4a67 885 aPolyNodes.SetValue (0, aNbPolyNodes);
886
887 if (!MeshVS_Tool::GetAverageNormal (aPolyNodes, aNorm))
888 {
889 aNorm.SetCoord (0.0, 0.0, 1.0);
890 }
891 }
7fd59977 892
37ac4a67 893 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbPolyNodes - 2; ++aNodeIdx) // triangulate polygon
894 {
895 for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx) // generate sub-triangle
7fd59977 896 {
37ac4a67 897 if (theIsShaded)
898 {
899 theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
900 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
901 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3),
902 aNorm.X(),
903 aNorm.Y(),
904 aNorm.Z());
905 }
906 else
907 {
908 theArray->AddVertex (aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
909 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
910 aPolyNodes.Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
911 }
7fd59977 912 }
7fd59977 913 }
914 }
915 }
37ac4a67 916 else if (theIsSelected)
7fd59977 917 {
37ac4a67 918 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
7fd59977 919 {
37ac4a67 920 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
921
922 Standard_Real aFaceCenter[] = { 0.0, 0.0, 0.0 };
923
924 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aFaceNodes.Length(); ++aNodeIdx)
7fd59977 925 {
37ac4a67 926 for (Standard_Integer aAxisIdx = 0; aAxisIdx < 3; ++aAxisIdx)
927 {
928 aFaceCenter[aAxisIdx] += theNodes.Value (aLow + 3 * aFaceNodes.Value (aNodeIdx) + aAxisIdx);
929 }
7fd59977 930 }
7fd59977 931
37ac4a67 932 aFaceCenter[0] /= aFaceNodes.Length();
933 aFaceCenter[1] /= aFaceNodes.Length();
934 aFaceCenter[2] /= aFaceNodes.Length();
935
936 for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
7fd59977 937 {
37ac4a67 938 for (Standard_Integer aSubIdx = 0; aSubIdx < 2; ++aSubIdx) // add segment
939 {
940 Standard_Integer anIdx = aFaceNodes.Value ((aNodeIdx + aSubIdx) % aNbNodes + 1);
941
942 Standard_Real aX = theNodes.Value (aLow + 3 * anIdx + 0);
943 Standard_Real aY = theNodes.Value (aLow + 3 * anIdx + 1);
944 Standard_Real aZ = theNodes.Value (aLow + 3 * anIdx + 2);
945
946 theArray->AddVertex (aFaceCenter[0] + theShrinkCoef * (aX - aFaceCenter[0]),
947 aFaceCenter[1] + theShrinkCoef * (aY - aFaceCenter[1]),
948 aFaceCenter[2] + theShrinkCoef * (aZ - aFaceCenter[2]));
949 }
7fd59977 950 }
951 }
952 }
953 else
954 {
37ac4a67 955 // Find all pairs of nodes (edges) to draw (will be drawn only once)
956 NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher> aEdgeMap;
7fd59977 957
37ac4a67 958 for (Standard_Integer aFaceIdx = theTopo->Lower(), topoup = theTopo->Upper(); aFaceIdx <= topoup; ++aFaceIdx)
7fd59977 959 {
37ac4a67 960 const TColStd_SequenceOfInteger& aFaceNodes = theTopo->Value (aFaceIdx);
961
962 for (Standard_Integer aNodeIdx = 0, aNbNodes = aFaceNodes.Length(); aNodeIdx < aNbNodes; ++aNodeIdx)
7fd59977 963 {
37ac4a67 964 const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
7fd59977 965
37ac4a67 966 aEdgeMap.Add (MeshVS_NodePair (aFaceNodes.Value (aNodeIdx + 1),
967 aFaceNodes.Value (aNextIdx + 1)));
7fd59977 968 }
969 }
970
37ac4a67 971 // Draw edges
972 for(NCollection_Map<MeshVS_NodePair, MeshVS_SymmetricPairHasher>::Iterator anIt (aEdgeMap); anIt.More(); anIt.Next())
7fd59977 973 {
37ac4a67 974 const Standard_Integer anIdx1 = aLow + 3 * anIt.Key().first;
975 const Standard_Integer anIdx2 = aLow + 3 * anIt.Key().second;
976
977 Standard_Real aX[] = { theNodes.Value (anIdx1 + 0), theNodes.Value (anIdx2 + 0) };
978 Standard_Real aY[] = { theNodes.Value (anIdx1 + 1), theNodes.Value (anIdx2 + 1) };
979 Standard_Real aZ[] = { theNodes.Value (anIdx1 + 2), theNodes.Value (anIdx2 + 2) };
980
981 if (theIsShrinked)
982 {
983 for (Standard_Integer anAxisIdx = 0; anAxisIdx < 2; ++anAxisIdx)
7fd59977 984 {
37ac4a67 985 aX[anAxisIdx] = aCenter[0] + theShrinkCoef * (aX[anAxisIdx] - aCenter[0]);
986 aY[anAxisIdx] = aCenter[1] + theShrinkCoef * (aY[anAxisIdx] - aCenter[1]);
987 aZ[anAxisIdx] = aCenter[2] + theShrinkCoef * (aZ[anAxisIdx] - aCenter[2]);
7fd59977 988 }
37ac4a67 989 }
7fd59977 990
37ac4a67 991 theArray->AddVertex (aX[0], aY[0], aZ[0]);
992 theArray->AddVertex (aX[1], aY[1], aZ[1]);
7fd59977 993 }
994 }
995}
996
997//================================================================
998// Function : HowManyPrimitives
999// Purpose :
1000//================================================================
1001void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo,
1002 const Standard_Boolean AsPolygons,
1003 const Standard_Boolean IsSelect,
1004 const Standard_Integer NbNodes,
1005 Standard_Integer& Vertices,
1006 Standard_Integer& Bounds)
1007{
eafb234b 1008 if( !Topo.IsNull() ) {
7fd59977 1009 if( AsPolygons || IsSelect )
1010 {
1011 Standard_Integer B = Topo->Upper()-Topo->Lower()+1;
1012 Bounds += B;
1013 for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ )
1014 Vertices += Topo->Value( i ).Length();
1015
1016 if( IsSelect )
1017 Vertices+=B;
1018 }
1019 else
1020 {
1021 Standard_Integer F = Topo->Upper()-Topo->Lower()+1,
1022 E = NbNodes + F - 2;
1023 // number of edges is obtained by Euler's expression for polyhedrons
1024
1025 Bounds += E;
1026 Vertices += 2*E;
1027 }
eafb234b 1028 }
7fd59977 1029}
1030
1031//================================================================
1032// Function : DrawArrays
1033// Purpose :
1034//================================================================
1035void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs,
37ac4a67 1036 const Handle(Graphic3d_ArrayOfPrimitives)& thePolygons,
1037 const Handle(Graphic3d_ArrayOfPrimitives)& theLines,
1038 const Handle(Graphic3d_ArrayOfPrimitives)& theLinkLines,
1039 const Handle(Graphic3d_ArrayOfPrimitives)& theVolumesInShad,
7fd59977 1040 const Standard_Boolean IsPolygonsEdgesOff,
1041 const Standard_Boolean IsSelected,
1042 const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
1043 const Handle(Graphic3d_AspectLine3d)& theLineAsp ) const
1044{
1045 if ( theFillAsp.IsNull() )
1046 return;
1047
1048 Standard_Boolean IsFacePolygons = ( !thePolygons.IsNull() && thePolygons->ItemNumber() > 0 ),
1049 IsVolumePolygons = ( !theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0 ),
1050 IsPolygons = IsFacePolygons || IsVolumePolygons,
1051 IsPolylines = ( !theLines.IsNull() && theLines->ItemNumber() > 0 ),
1052 IsLinkPolylines = ( !theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0 );
1053
b6472664 1054 Quantity_Color anIntColor = theFillAsp->InteriorColor();
1055 Quantity_Color aBackColor = theFillAsp->BackInteriorColor();
1056 Quantity_Color anEdgeColor = theFillAsp->EdgeColor();
1057 Standard_Real aWidth = theFillAsp->EdgeWidth();
7fd59977 1058
c3715b74 1059 Standard_Boolean isSupressBackFaces = Standard_False;
1060 Handle(MeshVS_Drawer) aDrawer = GetDrawer();
1061 if (!aDrawer.IsNull())
1062 {
1063 aDrawer->GetBoolean (MeshVS_DA_SupressBackFaces, isSupressBackFaces);
1064 }
1065
7fd59977 1066 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 )
1067 {
1068 Prs3d_Root::NewGroup ( Prs );
1069 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
b6472664 1070 aGroup->SetClosed (isSupressBackFaces == Standard_True);
1071 Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*theFillAsp);
7fd59977 1072 //if ( IsPolygonsEdgesOff )
b6472664 1073 aFillAsp->SetEdgeOff ();
7fd59977 1074 //else
b6472664 1075 // aFillAsp->SetEdgeOn ();
7fd59977 1076
1077 if( anIntColor!=aBackColor )
b6472664 1078 aFillAsp->SetDistinguishOn();
7fd59977 1079 else
b6472664 1080 aFillAsp->SetDistinguishOff();
7fd59977 1081
c3715b74 1082 aGroup->SetPrimitivesAspect (aFillAsp);
1083
7fd59977 1084 if( IsFacePolygons )
1085 {
7fd59977 1086 aGroup->AddPrimitiveArray ( thePolygons );
7fd59977 1087 }
1088
1089 if( IsVolumePolygons )
1090 {
7fd59977 1091 aGroup->AddPrimitiveArray ( theVolumesInShad );
7fd59977 1092 }
1093 }
1094
1095 if ( IsPolylines && !IsPolygonsEdgesOff )
1096 {
1097 Prs3d_Root::NewGroup ( Prs );
1098 Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
1099
7fd59977 1100 if ( IsSelected )
1101 aLGroup->SetPrimitivesAspect ( theLineAsp );
1102 else
1103 {
1104 aLGroup->SetPrimitivesAspect ( theFillAsp );
1105 aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d
1106 ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) );
1107 }
7fd59977 1108 aLGroup->AddPrimitiveArray ( theLines );
7fd59977 1109 }
1110
1111 if ( IsLinkPolylines )
1112 {
1113 Prs3d_Root::NewGroup ( Prs );
1114 Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs );
7fd59977 1115 if ( !IsSelected )
1116 aBeamGroup->SetPrimitivesAspect ( theFillAsp );
1117 aBeamGroup->SetPrimitivesAspect ( theLineAsp );
7fd59977 1118 aBeamGroup->AddPrimitiveArray ( theLinkLines );
7fd59977 1119 }
1120
1121 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 )
1122 {
1123 Prs3d_Root::NewGroup ( Prs );
1124 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
b6472664 1125 aGroup->SetClosed (isSupressBackFaces == Standard_True);
1126 Handle(Graphic3d_AspectFillArea3d) aFillAsp = new Graphic3d_AspectFillArea3d (*theFillAsp);
7fd59977 1127 //if ( IsPolygonsEdgesOff )
b6472664 1128 aFillAsp->SetEdgeOff ();
7fd59977 1129 //else
b6472664 1130 // aFillAsp->SetEdgeOn ();
7fd59977 1131
1132 if( anIntColor!=aBackColor )
b6472664 1133 aFillAsp->SetDistinguishOn();
7fd59977 1134 else
b6472664 1135 aFillAsp->SetDistinguishOff();
7fd59977 1136
c3715b74 1137 aGroup->SetPrimitivesAspect (aFillAsp);
1138
7fd59977 1139 if( IsFacePolygons )
1140 {
7fd59977 1141 aGroup->AddPrimitiveArray ( thePolygons );
7fd59977 1142 }
1143
1144 if( IsVolumePolygons )
1145 {
7fd59977 1146 aGroup->AddPrimitiveArray ( theVolumesInShad );
7fd59977 1147 }
1148 }
1149}
1150
1151//================================================================
1152// Function : CalculateCenter
1153// Purpose :
1154//================================================================
1155void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords,
1156 const Standard_Integer NbNodes,
1157 Standard_Real &xG,
1158 Standard_Real &yG,
1159 Standard_Real &zG)
1160{
1161 xG = yG = zG = 0;
1162 if ( NbNodes < 4 )
1163 {
1164 for ( Standard_Integer k=1; k<=NbNodes; k++)
1165 {
1166 xG += theCoords(3*k-2);
1167 yG += theCoords(3*k-1);
1168 zG += theCoords(3*k);
1169 }
1170 xG /= Standard_Real(NbNodes);
1171 yG /= Standard_Real(NbNodes);
1172 zG /= Standard_Real(NbNodes);
1173 }
1174 else
1175 {
1176 Standard_Integer a = 1, b = 3;
1177 xG = ( theCoords( 3*a-2 ) + theCoords( 3*b-2 ) ) / 2.0;
1178 yG = ( theCoords( 3*a-1 ) + theCoords( 3*b-1 ) ) / 2.0;
1179 zG = ( theCoords( 3*a ) + theCoords( 3*b ) ) / 2.0;
1180 }
1181}