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