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