0022627: Change OCCT memory management defaults
[occt.git] / src / MeshVS / MeshVS_MeshPrsBuilder.cxx
CommitLineData
7fd59977 1// File: MeshVS_MeshPrsBuilder.cxx
2// Created: Tue Sep 16 2003
3// Author: Alexander SOLOVYOV
4// Copyright: Open CASCADE 2003
5
6#include <MeshVS_MeshPrsBuilder.ixx>
7
8#include <Prs3d_Root.hxx>
9#include <Prs3d_ShadingAspect.hxx>
10#include <Prs3d_LineAspect.hxx>
11#include <Prs3d_PointAspect.hxx>
12
13#include <Graphic3d_AspectLine3d.hxx>
14#include <Graphic3d_AspectFillArea3d.hxx>
15#include <Graphic3d_AspectMarker3d.hxx>
16#include <Graphic3d_ArrayOfPolygons.hxx>
17#include <Graphic3d_ArrayOfPolylines.hxx>
18#include <Graphic3d_Array1OfVertex.hxx>
19#include <Graphic3d_Group.hxx>
20
21#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
22#include <TColStd_ListIteratorOfListOfReal.hxx>
23#include <TColStd_MapIntegerHasher.hxx>
24#include <TColStd_Array1OfReal.hxx>
25#include <TColStd_Array1OfInteger.hxx>
26#include <TColStd_SequenceOfInteger.hxx>
27#include <TColStd_PackedMapOfInteger.hxx>
28#include <TColStd_HPackedMapOfInteger.hxx>
29
30#include <Quantity_NameOfColor.hxx>
31#include <Aspect_InteriorStyle.hxx>
32#include <Select3D_SensitivePoint.hxx>
33
34#include <MeshVS_DataSource.hxx>
35#include <MeshVS_Drawer.hxx>
36#include <MeshVS_Mesh.hxx>
37#include <MeshVS_Tool.hxx>
38#include <MeshVS_DrawerAttribute.hxx>
39#include <MeshVS_MapOfTwoNodes.hxx>
40#include <MeshVS_Buffer.hxx>
41
42//================================================================
43// Function : Constructor MeshVS_MeshPrsBuilder
44// Purpose :
45//================================================================
46MeshVS_MeshPrsBuilder::MeshVS_MeshPrsBuilder ( const Handle(MeshVS_Mesh)& Parent,
47 const Standard_Integer& DisplayModeMask,
48 const Handle (MeshVS_DataSource)& DS,
49 const Standard_Integer Id,
50 const MeshVS_BuilderPriority& Priority )
51: MeshVS_PrsBuilder ( Parent, DisplayModeMask, DS, Id, Priority )
52{
53}
54
55//================================================================
56// Function : Build
57// Purpose :
58//================================================================
59void MeshVS_MeshPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Prs,
60 const TColStd_PackedMapOfInteger& IDs,
61 TColStd_PackedMapOfInteger& IDsToExclude,
62 const Standard_Boolean IsElement,
63 const Standard_Integer DisplayMode ) const
64{
65 if ( DisplayMode <= 0 )
66 return;
67
68 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
69 Standard_Integer Extent = IDs.Extent();
70
71 if ( HasHilightFlag && Extent == 1)
72 BuildHilightPrs ( Prs, IDs, IsElement );
73 else if ( IsElement )
74 BuildElements ( Prs, IDs, IDsToExclude, DisplayMode );
75 else
76 BuildNodes ( Prs, IDs, IDsToExclude, DisplayMode );
77}
78
79//================================================================
80// Function : BuildNodes
81// Purpose :
82//================================================================
83void MeshVS_MeshPrsBuilder::BuildNodes ( const Handle(Prs3d_Presentation)& Prs,
84 const TColStd_PackedMapOfInteger& IDs,
85 TColStd_PackedMapOfInteger& IDsToExclude,
86 const Standard_Integer DisplayMode ) const
87{
88 Handle( MeshVS_DataSource ) aSource = GetDataSource();
89 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
90 Handle (Graphic3d_AspectMarker3d) aNodeMark =
91 MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
92 if ( aSource.IsNull() || aDrawer.IsNull() || aNodeMark.IsNull() )
93 return;
94
95 Standard_Boolean DisplayFreeNodes = Standard_True;
96 aDrawer->GetBoolean( MeshVS_DA_DisplayNodes, DisplayFreeNodes );
97 Standard_Boolean HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 );
98 Standard_Boolean HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 );
99
100 Standard_Real aCoordsBuf[ 3 ];
101 TColStd_Array1OfReal aCoords( *aCoordsBuf, 1, 3 );
102 Standard_Integer NbNodes;
103 MeshVS_EntityType aType;
104
105 if ( !DisplayFreeNodes )
106 return;
107
108 TColStd_PackedMapOfInteger anIDs;
109 anIDs.Assign( IDs );
110 if ( !HasSelectFlag && !HasHilightFlag )
111 {
112 // subtract the hidden nodes and ids to exclude (to minimise allocated memory)
113 Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = myParentMesh->GetHiddenNodes();
114 if ( !aHiddenNodes.IsNull() )
115 anIDs.Subtract( aHiddenNodes->Map() );
116 }
117 anIDs.Subtract( IDsToExclude );
118
119 Standard_Integer upper = anIDs.Extent();
120 if ( upper<=0 )
121 return;
122
123 Graphic3d_Array1OfVertex aNodePoints ( 1, upper );
124 Standard_Integer k=0;
125 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
126 for( ; it.More(); it.Next() )
127 {
128 Standard_Integer aKey = it.Key();
129 if ( aSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) )
130 {
131 if ( IsExcludingOn() )
132 IDsToExclude.Add (aKey);
133 k++;
134 aNodePoints.SetValue ( k, Graphic3d_Vertex ( aCoords(1), aCoords(2), aCoords(3) ) );
135 }
136 }
137
138 if ( k>0 )
139 {
140 Prs3d_Root::NewGroup ( Prs );
141 Handle (Graphic3d_Group) aNodeGroup = Prs3d_Root::CurrentGroup ( Prs );
142 aNodeGroup->SetPrimitivesAspect ( aNodeMark );
143
144 aNodeGroup->BeginPrimitives();
145 aNodeGroup->MarkerSet ( aNodePoints );
146 aNodeGroup->EndPrimitives();
147 }
148}
149
150//================================================================
151// Function : BuildElements
152// Purpose :
153//================================================================
154void MeshVS_MeshPrsBuilder::BuildElements( const Handle(Prs3d_Presentation)& Prs,
155 const TColStd_PackedMapOfInteger& IDs,
156 TColStd_PackedMapOfInteger& IDsToExclude,
157 const Standard_Integer DisplayMode ) const
158{
159 Standard_Integer maxnodes;
160
161 Handle (MeshVS_DataSource) aSource = GetDataSource();
162 if ( aSource.IsNull() )
163 return;
164
165 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
166 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
167 maxnodes <= 0 )
168 return;
169
170 //----------- extract useful display mode flags ----------
171 Standard_Integer aDispMode = ( DisplayMode & GetFlags() );
172 if ( ( aDispMode & MeshVS_DMF_DeformedMask) != 0 )
173 {
174 aDispMode /= MeshVS_DMF_DeformedPrsWireFrame;
175 // This transformation turns deformed mesh flags to real display modes
176 }
177 aDispMode &= MeshVS_DMF_OCCMask;
178 //--------------------------------------------------------
179
180 Standard_Real aShrinkCoef;
181 aDrawer->GetDouble ( MeshVS_DA_ShrinkCoeff, aShrinkCoef );
182
183 Standard_Boolean IsWireFrame = ( aDispMode==MeshVS_DMF_WireFrame ),
184 IsShading = ( aDispMode==MeshVS_DMF_Shading ),
185 IsShrink = ( aDispMode==MeshVS_DMF_Shrink ),
186 HasHilightFlag = ( ( DisplayMode & MeshVS_DMF_HilightPrs ) != 0 ),
187 HasSelectFlag = ( ( DisplayMode & MeshVS_DMF_SelectionPrs ) != 0 ),
188 IsMeshReflect, IsMeshAllowOverlap, IsReflect, IsMeshSmoothShading = Standard_False;
189
190 aDrawer->GetBoolean ( MeshVS_DA_Reflection, IsMeshReflect );
191 aDrawer->GetBoolean ( MeshVS_DA_IsAllowOverlapped, IsMeshAllowOverlap );
192 IsReflect = ( IsMeshReflect && !HasHilightFlag );
193 aDrawer->GetBoolean ( MeshVS_DA_SmoothShading, IsMeshSmoothShading );
194
195 // display mode for hilighted prs of groups
196 IsShrink = ( IsShrink && !HasHilightFlag );
197 IsShading = ( IsShading || HasHilightFlag );
198
199 //---------- Creating AspectFillArea3d and AspectLine3d -------------
200 Graphic3d_MaterialAspect AMat;
201 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
202 if ( !IsReflect )
203 {
204 AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
205 AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
206 AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
207 AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
208 }
209 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
210 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d ( GetDrawer() );
211 //-------------------------------------------------------------------
212
213 Standard_Boolean IsOverlapControl =
214 !IsMeshAllowOverlap && ( IsWireFrame || IsShading ) && !HasSelectFlag;
215
216 Handle (Graphic3d_ArrayOfPolygons) aPolygons, aVolumes;
217 Handle (Graphic3d_ArrayOfPolylines) aPolylines, aLinkPolylines;
218
219 Standard_Integer PolygonVerticesFor3D = 0, PolygonBoundsFor3D = 0,
220 PolylineVerticesFor3D = 0, PolylineBoundsFor3D = 0,
221 NbNodes;
222
223 // subtract the hidden elements and ids to exclude (to minimise allocated memory)
224 TColStd_PackedMapOfInteger anIDs;
225 anIDs.Assign( IDs );
226 Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
227 if ( !aHiddenElems.IsNull() )
228 anIDs.Subtract( aHiddenElems->Map() );
229 anIDs.Subtract( IDsToExclude );
230
231 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
232 TColStd_MapIteratorOfPackedMapOfInteger it (anIDs);
233 for( ; it.More(); it.Next() )
234 {
235 Standard_Integer aKey = it.Key();
236 if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
237 {
238 if( !HasSelectFlag )
239 HowManyPrimitives( aTopo, Standard_True, HasSelectFlag, NbNodes,
240 PolygonVerticesFor3D, PolygonBoundsFor3D );
241 HowManyPrimitives( aTopo, Standard_False, HasSelectFlag, NbNodes,
242 PolylineVerticesFor3D, PolylineBoundsFor3D );
243 }
244 }
245
246 Standard_Integer Extent = anIDs.Extent();
247
248 if ( IsReflect )
249 {
250 aPolygons = new Graphic3d_ArrayOfPolygons
251 ( maxnodes*Extent, Extent, 0, Standard_True );
252 aVolumes = new Graphic3d_ArrayOfPolygons
253 ( PolygonVerticesFor3D, PolygonBoundsFor3D, 0, Standard_True );
254 }
255 else
256 {
257 aPolygons = new Graphic3d_ArrayOfPolygons( maxnodes*Extent, Extent );
258 aVolumes = new Graphic3d_ArrayOfPolygons ( PolygonVerticesFor3D, PolygonBoundsFor3D );
259 }
260
261 Standard_Integer howMany = 1;
262 if ( IsOverlapControl )
263 howMany = 2;
264
265 Standard_Boolean showEdges = Standard_True;
266 aDrawer->GetBoolean( MeshVS_DA_ShowEdges, showEdges );
267
268 showEdges = IsWireFrame || showEdges;
269 if ( showEdges )
270 {
271 aPolylines = new Graphic3d_ArrayOfPolylines ( ( maxnodes+1 )*Extent + PolylineVerticesFor3D,
272 howMany * Extent + PolylineBoundsFor3D );
273 aLinkPolylines = new Graphic3d_ArrayOfPolylines ( 2*Extent, Extent );
274 }
275
276 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
277 TColStd_Array1OfReal aCoords( aCoordsBuf, 1, 3*maxnodes );
278 MeshVS_EntityType aType;
279
280 TColStd_PackedMapOfInteger aCustomElements;
281
282 Quantity_Color anOldEdgeColor;
283 Aspect_InteriorStyle anIntType;
284 Quantity_Color anIntColor, anEdgeColor;
285 Aspect_TypeOfLine aLine;
286 Standard_Real aWidth;
287
288 MeshVS_TwoNodes aTwoNodes;
289 aFill->Values ( anIntType, anIntColor, anEdgeColor, aLine, aWidth );
290
291 MeshVS_MapOfTwoNodes aLinkNodes;
292 if ( showEdges && IsOverlapControl )
293 // Forbid drawings of edges, which overlap with some links
294 for( it.Reset(); it.More(); it.Next() )
295 {
296 Standard_Integer aKey = it.Key();
297 if ( aSource->GetGeomType ( aKey, Standard_True, aType ) &&
298 aType == MeshVS_ET_Link )
299 {
300 MeshVS_Buffer aNodesBuf (maxnodes * sizeof(Standard_Integer));
301 TColStd_Array1OfInteger aNodes (aNodesBuf, 1, maxnodes);
302 Standard_Integer nbNodes;
303 if ( aSource->GetNodesByElement( aKey, aNodes, nbNodes ) &&
304 nbNodes == 2 )
305 {
306 aTwoNodes.First = aNodes(1);
307 aTwoNodes.Second = aNodes(2);
308 aLinkNodes.Add ( aTwoNodes );
309 }
310 }
311 }
312
313 for( it.Reset(); it.More(); it.Next() )
314 {
315 Standard_Integer aKey = it.Key();
316
317 if ( ! aSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType ) )
318 continue;
319
320 switch ( aType )
321 {
322 case MeshVS_ET_Volume :
323 if( IsExcludingOn() )
324 IDsToExclude.Add (aKey);
325 if( aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
326 {
327 // !!! TO DO: Overlap control
328 // add wireframe presentation (draw edges for shading mode as well)
329 if ( showEdges )
330 AddVolumePrs ( aTopo, aCoords, NbNodes, aPolylines, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
331
332 // add shading presentation
333 if ( ( IsShading || IsShrink ) && !HasSelectFlag )
334 AddVolumePrs ( aTopo, aCoords, NbNodes, aVolumes, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
335
336 /*
337 Handle( Graphic3d_ArrayOfPrimitives ) anArr = aVolumes;
338 if( IsWireFrame || HasSelectFlag )
339 anArr = aPolylines;
340
341 AddVolumePrs ( aTopo, aCoords, NbNodes, anArr, IsReflect, IsShrink, HasSelectFlag, aShrinkCoef );
342 */
343 }
344 break;
345
346 case MeshVS_ET_Link :
347 if( IsExcludingOn() )
348 IDsToExclude.Add (aKey);
349 if ( showEdges )
350 AddLinkPrs ( aCoords, aLinkPolylines, IsShrink || HasSelectFlag, aShrinkCoef );
351 break;
352
353 case MeshVS_ET_Face :
354 if( IsExcludingOn() )
355 IDsToExclude.Add (aKey);
356 if ( showEdges && IsOverlapControl )
357 {
358 MeshVS_Buffer aNodesBuf (NbNodes * sizeof(Standard_Integer));
359 TColStd_Array1OfInteger aNodes (aNodesBuf, 1, NbNodes);
360 if ( !aSource->GetNodesByElement( aKey, aNodes, NbNodes ) )
361 continue;
362
363 Standard_Integer Last = 0;
364 for ( Standard_Integer i=1; i<=NbNodes; i++ )
365 {
366 if ( i==1 )
367 aTwoNodes.First = aNodes(i);
368 else
369 aTwoNodes.First = aTwoNodes.Second;
370
371 aTwoNodes.Second = ( i<NbNodes ? aNodes(i+1) : aNodes(1) );
372 if ( aLinkNodes.Contains ( aTwoNodes ) )
373 {
374 aPolylines->AddBound ( i-Last );
375 for (Standard_Integer j = Last+1; j<=i; j++)
376 aPolylines->AddVertex ( aCoords(3*j-2), aCoords(3*j-1), aCoords(3*j) );
377 Last = i;
378 }
379 }
380 if ( NbNodes-Last > 0 )
381 {
382 aPolylines->AddBound ( NbNodes-Last+1 );
383 for (Standard_Integer j = Last+1; j<=NbNodes; j++)
384 aPolylines->AddVertex ( aCoords(3*j-2), aCoords(3*j-1), aCoords(3*j) );
385
386 aPolylines->AddVertex ( aCoords(1), aCoords(2), aCoords(3) );
387 }
388 }
389
390 if ( !IsOverlapControl || IsShading )
391 {
392 if ( !IsOverlapControl && showEdges )
393 AddFaceWirePrs(aCoords, NbNodes, aPolylines,
394 IsShrink || HasSelectFlag, aShrinkCoef );
395 if ( ( IsShading || IsShrink ) && !HasSelectFlag )
396 AddFaceSolidPrs(aKey, aCoords, NbNodes, maxnodes, aPolygons,
397 IsReflect, IsShrink || HasSelectFlag,
398 aShrinkCoef, IsMeshSmoothShading );
399 }
400 break;
401
402 default:
403 aCustomElements.Add( aKey );
404 break;
405 }
406 }
407
408 if ( IsShrink )
409 {
410 anOldEdgeColor = anEdgeColor;
411 aFill->SetEdgeColor ( Quantity_NOC_BLACK );
412 }
413
414 DrawArrays ( Prs, aPolygons, aPolylines, aLinkPolylines, aVolumes,
415 !showEdges, HasSelectFlag, aFill, aBeam );
416
417 if ( !aCustomElements.IsEmpty() )
418 CustomBuild ( Prs, aCustomElements, IDsToExclude, DisplayMode );
419
420 if( IsShrink )
421 aFill->SetEdgeColor( anOldEdgeColor );
422}
423
424//================================================================
425// Function : BuildHilightPrs
426// Purpose :
427//================================================================
428void MeshVS_MeshPrsBuilder::BuildHilightPrs ( const Handle(Prs3d_Presentation)& Prs,
429 const TColStd_PackedMapOfInteger& IDs,
430 const Standard_Boolean IsElement ) const
431{
432 Standard_Integer maxnodes;
433
434 Handle (MeshVS_DataSource) aSource = GetDataSource();
435 if ( aSource.IsNull() || IDs.IsEmpty() )
436 return;
437
438 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
439 if ( aDrawer.IsNull() || !aDrawer->GetInteger ( MeshVS_DA_MaxFaceNodes, maxnodes ) ||
440 maxnodes <= 0 )
441 return;
442
443 MeshVS_Buffer aCoordsBuf (3*maxnodes*sizeof(Standard_Real));
444 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3*maxnodes);
445
446 Graphic3d_MaterialAspect AMat;
447 aDrawer->GetMaterial ( MeshVS_DA_FrontMaterial, AMat );
448 AMat.SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
449 AMat.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
450 AMat.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
451 AMat.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
452
453 Handle( Graphic3d_AspectFillArea3d ) aFill = MeshVS_Tool::CreateAspectFillArea3d( GetDrawer(), AMat );
454 Handle( Graphic3d_AspectLine3d ) aBeam = MeshVS_Tool::CreateAspectLine3d( GetDrawer() );
455 Handle( Graphic3d_AspectMarker3d ) aNodeMark = MeshVS_Tool::CreateAspectMarker3d( GetDrawer() );
456
457 // Hilight one element or node
458 TColStd_MapIteratorOfPackedMapOfInteger it (IDs);
459 Standard_Integer ID = it.Key(), NbNodes;
460 MeshVS_EntityType aType;
461
462 if ( !aSource->GetGeom ( ID, IsElement, aCoords, NbNodes, aType ) )
463 return;
464
465 Prs3d_Root::NewGroup ( Prs );
466 Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup ( Prs );
467
468 switch ( aType )
469 {
470 case MeshVS_ET_Node :
471 {
472 aHilightGroup->SetPrimitivesAspect ( aNodeMark );
473 aHilightGroup->Marker ( Graphic3d_Vertex ( aCoords(1), aCoords(2), aCoords(3) ) );
474 }
475 break;
476
477 case MeshVS_ET_Link:
478 {
479 aHilightGroup->SetPrimitivesAspect ( aBeam );
480 aHilightGroup->Polyline ( Graphic3d_Vertex ( aCoords(1), aCoords(2), aCoords(3) ),
481 Graphic3d_Vertex ( aCoords(4), aCoords(5), aCoords(6) ) );
482 }
483 break;
484
485 case MeshVS_ET_Face:
486 if ( NbNodes > 0 )
487 {
488 Standard_Real X, Y, Z;
489 aHilightGroup->SetPrimitivesAspect ( aFill );
490 Graphic3d_Array1OfVertex aVArr ( 1, NbNodes );
491
492 for ( Standard_Integer k=1; k<=NbNodes; k++)
493 {
494 X = aCoords(3*k-2);
495 Y = aCoords(3*k-1);
496 Z = aCoords(3*k);
497 aVArr.SetValue ( k, Graphic3d_Vertex ( X, Y, Z ) );
498 }
499 aHilightGroup->Polygon ( aVArr );
500 }
501 break;
502
503 case MeshVS_ET_Volume:
504 if( NbNodes > 0 )
505 {
506 Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
507
508 aHilightGroup->SetPrimitivesAspect ( aFill );
509
510 if( aSource->Get3DGeom( ID, NbNodes, aTopo ) )
511 {
512 Standard_Integer low = aTopo->Lower(), up = aTopo->Upper(), i, j, m, ind;
513 for( i=low; i<=up; i++ )
514 {
515 const TColStd_SequenceOfInteger& aSeq = aTopo->Value( i );
516 m = aSeq.Length();
517 Graphic3d_Array1OfVertex aVArr( 1, m );
518 for( j=1; j<=m; j++ )
519 {
520 ind = aSeq.Value( j );
521 aVArr.SetValue( j, Graphic3d_Vertex( aCoords( 3*ind+1 ),
522 aCoords( 3*ind+2 ),
523 aCoords( 3*ind+3 ) ) );
524 }
525 aHilightGroup->Polygon ( aVArr );
526 }
527 }
528 }
529 break;
530
531 default:
532 {
533 TColStd_PackedMapOfInteger tmp;
534 CustomBuild ( Prs, IDs, tmp, MeshVS_DMF_HilightPrs );
535 }
536 break;
537 }
538}
539
540//================================================================
541// Function : AddLinkPrs
542// Purpose :
543//================================================================
544void MeshVS_MeshPrsBuilder::AddLinkPrs (const TColStd_Array1OfReal& theCoords,
545 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
546 const Standard_Boolean IsShrinked,
547 const Standard_Real ShrinkCoef) const
548{
549 Standard_Real x1 = theCoords(1);
550 Standard_Real y1 = theCoords(2);
551 Standard_Real z1 = theCoords(3);
552 Standard_Real x2 = theCoords(4);
553 Standard_Real y2 = theCoords(5);
554 Standard_Real z2 = theCoords(6);
555 Standard_Real xG, yG, zG;
556
557 if ( IsShrinked )
558 {
559 xG = (x1+x2)/2.0;
560 yG = (y1+y2)/2.0;
561 zG = (z1+z2)/2.0;
562 x1 = (x1 - xG) * ShrinkCoef + xG;
563 x2 = 2.0*xG - x1;
564 y1 = (y1 - yG) * ShrinkCoef + yG;
565 y2 = 2.0*yG - y1;
566 z1 = (z1 - zG) * ShrinkCoef + zG;
567 z2 = 2.0*zG - z1;
568 }
569 theLines->AddBound ( 2 );
570 theLines->AddVertex ( x1, y1, z1 );
571 theLines->AddVertex ( x2, y2, z2 );
572}
573
574//================================================================
575// Function : AddFaceWirePrs
576// Purpose :
577//================================================================
578void MeshVS_MeshPrsBuilder::AddFaceWirePrs (const TColStd_Array1OfReal& theCoords,
579 const Standard_Integer NbNodes,
580 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
581 const Standard_Boolean IsShrinked,
582 const Standard_Real ShrinkCoef) const
583{
584 Standard_Real xG, yG, zG, X, Y, Z, startX=0., startY=0., startZ=0.;
585 theLines->AddBound ( NbNodes+1 );
586 if ( IsShrinked )
587 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
588
589 for ( Standard_Integer k=1; k<=NbNodes; k++)
590 {
591 X = theCoords(3*k-2);
592 Y = theCoords(3*k-1);
593 Z = theCoords(3*k);
594 if ( IsShrinked )
595 {
596 X = (X - xG) * ShrinkCoef + xG;
597 Y = (Y - yG) * ShrinkCoef + yG;
598 Z = (Z - zG) * ShrinkCoef + zG;
599 }
600 if( k==1 )
601 {
602 startX = X; startY = Y; startZ = Z;
603 }
604 theLines->AddVertex ( X, Y, Z );
605 }
606 theLines->AddVertex( startX, startY, startZ );
607}
608
609//================================================================
610// Function : AddFaceSolidPrs
611// Purpose :
612//================================================================
613void MeshVS_MeshPrsBuilder::AddFaceSolidPrs (const Standard_Integer ID,
614 const TColStd_Array1OfReal& theCoords,
615 const Standard_Integer NbNodes,
616 const Standard_Integer MaxNodes,
617 const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
618 const Standard_Boolean IsReflected,
619 const Standard_Boolean IsShrinked,
620 const Standard_Real ShrinkCoef,
621 const Standard_Boolean IsMeshSmoothShading) const
622{
623 Handle( MeshVS_DataSource ) aDS = myParentMesh->GetDataSource();
624 if ( aDS.IsNull() )
625 return;
626
627 Standard_Real xG, yG, zG, X, Y, Z, nx, ny, nz;
628 thePolygons->AddBound ( NbNodes );
629 if ( IsShrinked )
630 CalculateCenter( theCoords, NbNodes, xG, yG, zG );
631
632 Standard_Boolean allNormals = Standard_True;
633 Standard_Integer k;
634
635 if( IsReflected )
636 {
637 if( IsMeshSmoothShading )
638 for( k=1; k<=NbNodes && allNormals; k++ )
639 allNormals = aDS->GetNodeNormal (k, ID, nx, ny, nz);
640 if( !IsMeshSmoothShading || !allNormals )
641 aDS->GetNormal( ID, MaxNodes, nx, ny, nz );
642 }
643
644 for ( k=1; k<=NbNodes; k++)
645 {
646 X = theCoords(3*k-2);
647 Y = theCoords(3*k-1);
648 Z = theCoords(3*k);
649 if ( IsShrinked )
650 {
651 X = (X - xG) * ShrinkCoef + xG;
652 Y = (Y - yG) * ShrinkCoef + yG;
653 Z = (Z - zG) * ShrinkCoef + zG;
654 }
655
656 if ( IsReflected )
657 {
658 if( IsMeshSmoothShading && allNormals )
659 aDS->GetNodeNormal (k, ID, nx, ny, nz);
660 thePolygons->AddVertex ( X, Y, Z, nx, ny, nz );
661 }
662 else
663 thePolygons->AddVertex ( X, Y, Z );
664 }
665}
666
667//================================================================
668// Function : AddVolumePrs
669// Purpose :
670//================================================================
671void MeshVS_MeshPrsBuilder::AddVolumePrs (const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo,
672 const TColStd_Array1OfReal& Nodes,
673 const Standard_Integer NbNodes,
674 const Handle( Graphic3d_ArrayOfPrimitives )& Array,
675 const Standard_Boolean IsReflected,
676 const Standard_Boolean IsShrinked,
677 const Standard_Boolean IsSelect,
678 const Standard_Real ShrinkCoef)
679{
680 Standard_Real c[3]; c[0] = c[1] = c[2] = 0.0;
681 Standard_Integer low = Nodes.Lower(), n=NbNodes;
682
683 if( Topo.IsNull() || Array.IsNull() )
684 return;
685
686 if( IsShrinked )
687 {
688 for( Standard_Integer i=0; i<3*n; i++ )
689 c[i%3] += Nodes.Value( low + i );
690
691 c[0] /= n;
692 c[1] /= n;
693 c[2] /= n;
694 }
695
696 Standard_Boolean IsPolygons = Array->IsKind( STANDARD_TYPE( Graphic3d_ArrayOfPolygons ) );
697 Standard_Real x[2], y[2], z[2];
698 Standard_Integer ind;
699 gp_Vec norm;
700
701 if( IsPolygons )
702 {
703 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
704 {
705 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
706
707 Standard_Integer m = aSeq.Length();
708 Array->AddBound( m );
709
710 norm.SetCoord( 0, 0, 0 );
711 if( IsReflected )
712 {
713 MeshVS_Buffer PolyNodesBuf (3*m*sizeof(Standard_Real));
714 TColStd_Array1OfReal PolyNodes( PolyNodesBuf, 0, 3*m );
715 PolyNodes.SetValue( 0, m );
716 for( Standard_Integer j=1; j<=m; j++ )
717 {
718 ind = aSeq.Value( j );
719 PolyNodes.SetValue( 3*j-2, Nodes.Value( low+3*ind ) );
720 PolyNodes.SetValue( 3*j-1, Nodes.Value( low+3*ind+1 ) );
721 PolyNodes.SetValue( 3*j, Nodes.Value( low+3*ind+2 ) );
722 }
723
724 // compute normal
725 // if( !MeshVS_Tool::GetNormal( PolyNodes, norm ) )
726 // norm.SetCoord( 0, 0, 0 );
727 MeshVS_Tool::GetAverageNormal( PolyNodes, norm );
728 }
729
730 Standard_Real nx = norm.X(), ny = norm.Y(), nz = norm.Z();
731
732
733 for( Standard_Integer j=1; j<=m; j++ )
734 {
735 ind = aSeq.Value( j );
736 x[0] = Nodes.Value( low + 3*ind );
737 y[0] = Nodes.Value( low + 3*ind+1 );
738 z[0] = Nodes.Value( low + 3*ind+2 );
739
740 if( IsShrinked )
741 {
742 x[0] = c[0] + ShrinkCoef * ( x[0]-c[0] );
743 y[0] = c[1] + ShrinkCoef * ( y[0]-c[1] );
744 z[0] = c[2] + ShrinkCoef * ( z[0]-c[2] );
745 }
746
747 if( IsReflected )
748 Array->AddVertex( x[0], y[0], z[0], nx, ny, nz );
749 else
750 Array->AddVertex( x[0], y[0], z[0] );
751 }
752 }
753 }
754 else if( IsSelect )
755 {
756 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
757 {
758 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
759 Standard_Real pc[3]; pc[0] = pc[1] = pc[2] = 0;
760 Standard_Integer j,m;
761 for( j=1, m=aSeq.Length(); j<=m; j++ )
762 {
763 ind = aSeq.Value( j );
764 for( Standard_Integer k=0; k<3; k++ )
765 pc[k] += Nodes.Value( low + 3*ind+k );
766 }
767 pc[0] /= m;
768 pc[1] /= m;
769 pc[2] /= m;
770
771 Array->AddBound( m+1 );
772 for( j=1, m=aSeq.Length(); j<=m+1; j++ )
773 {
774 ind = aSeq.Value( (j-1)%m + 1 );
775 x[0] = Nodes.Value( low + 3*ind );
776 y[0] = Nodes.Value( low + 3*ind+1 );
777 z[0] = Nodes.Value( low + 3*ind+2 );
778 x[0] = pc[0] + ShrinkCoef * ( x[0]-pc[0] );
779 y[0] = pc[1] + ShrinkCoef * ( y[0]-pc[1] );
780 z[0] = pc[2] + ShrinkCoef * ( z[0]-pc[2] );
781 Array->AddVertex( x[0], y[0], z[0] );
782 }
783 }
784 }
785 else
786 {
787 Standard_Integer F, S=0, k;
788
789 // Find all pairs of nodes (edges) to draw;
790 // map is used to ensure that each edge will be drawn only once
791 TColStd_PackedMapOfInteger aMap;
792 for( Standard_Integer i=Topo->Lower(), topoup=Topo->Upper(); i<=topoup; i++ )
793 {
794 const TColStd_SequenceOfInteger& aSeq = Topo->Value( i );
795 for( Standard_Integer j=1, m=aSeq.Length(); j<=m; j++ )
796 {
797 if( j==1 )
798 F = aSeq.Value( j );
799 else
800 F = S;
801
802 S = j<m ? aSeq.Value( j+1 ) : aSeq.Value( 1 );
803
804 if( F<S )
805 aMap.Add( F + NbNodes * S );
806 else
807 aMap.Add( S + NbNodes * F );
808 }
809 }
810
811 // draw edges
812 TColStd_MapIteratorOfPackedMapOfInteger anIt( aMap );
813 for( ; anIt.More(); anIt.Next() )
814 {
815 F = low + 3*(anIt.Key()%NbNodes);
816 S = low + 3*(anIt.Key()/NbNodes);
817
818 x[0] = Nodes.Value( F );
819 y[0] = Nodes.Value( F+1 );
820 z[0] = Nodes.Value( F+2 );
821 x[1] = Nodes.Value( S );
822 y[1] = Nodes.Value( S+1 );
823 z[1] = Nodes.Value( S+2 );
824
825 if( IsShrinked )
826 for( k=0; k<2; k++ )
827 {
828 x[k] = c[0] + ShrinkCoef * ( x[k]-c[0] );
829 y[k] = c[1] + ShrinkCoef * ( y[k]-c[1] );
830 z[k] = c[2] + ShrinkCoef * ( z[k]-c[2] );
831 }
832
833 Array->AddBound( 2 );
834 Array->AddVertex( x[0], y[0], z[0] );
835 Array->AddVertex( x[1], y[1], z[1] );
836 }
837 }
838}
839
840//================================================================
841// Function : HowManyPrimitives
842// Purpose :
843//================================================================
844void MeshVS_MeshPrsBuilder::HowManyPrimitives (const Handle(MeshVS_HArray1OfSequenceOfInteger)& Topo,
845 const Standard_Boolean AsPolygons,
846 const Standard_Boolean IsSelect,
847 const Standard_Integer NbNodes,
848 Standard_Integer& Vertices,
849 Standard_Integer& Bounds)
850{
851 if( !Topo.IsNull() )
852 if( AsPolygons || IsSelect )
853 {
854 Standard_Integer B = Topo->Upper()-Topo->Lower()+1;
855 Bounds += B;
856 for( Standard_Integer i=Topo->Lower(), n=Topo->Upper(); i<=n; i++ )
857 Vertices += Topo->Value( i ).Length();
858
859 if( IsSelect )
860 Vertices+=B;
861 }
862 else
863 {
864 Standard_Integer F = Topo->Upper()-Topo->Lower()+1,
865 E = NbNodes + F - 2;
866 // number of edges is obtained by Euler's expression for polyhedrons
867
868 Bounds += E;
869 Vertices += 2*E;
870 }
871}
872
873//================================================================
874// Function : DrawArrays
875// Purpose :
876//================================================================
877void MeshVS_MeshPrsBuilder::DrawArrays( const Handle(Prs3d_Presentation)& Prs,
878 const Handle(Graphic3d_ArrayOfPolygons)& thePolygons,
879 const Handle(Graphic3d_ArrayOfPolylines)& theLines,
880 const Handle(Graphic3d_ArrayOfPolylines)& theLinkLines,
881 const Handle(Graphic3d_ArrayOfPolygons)& theVolumesInShad,
882 const Standard_Boolean IsPolygonsEdgesOff,
883 const Standard_Boolean IsSelected,
884 const Handle(Graphic3d_AspectFillArea3d)& theFillAsp,
885 const Handle(Graphic3d_AspectLine3d)& theLineAsp ) const
886{
887 if ( theFillAsp.IsNull() )
888 return;
889
890 Standard_Boolean IsFacePolygons = ( !thePolygons.IsNull() && thePolygons->ItemNumber() > 0 ),
891 IsVolumePolygons = ( !theVolumesInShad.IsNull() && theVolumesInShad->ItemNumber() > 0 ),
892 IsPolygons = IsFacePolygons || IsVolumePolygons,
893 IsPolylines = ( !theLines.IsNull() && theLines->ItemNumber() > 0 ),
894 IsLinkPolylines = ( !theLinkLines.IsNull() && theLinkLines->ItemNumber() > 0 );
895
896 Aspect_InteriorStyle aStyle;
897 Quantity_Color anIntColor, aBackColor, anEdgeColor;
898 Aspect_TypeOfLine aType;
899 Standard_Real aWidth;
900
901 theFillAsp->Values( aStyle, anIntColor, aBackColor, anEdgeColor, aType, aWidth );
902
903 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()<0.01 )
904 {
905 Prs3d_Root::NewGroup ( Prs );
906 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
907
908 //if ( IsPolygonsEdgesOff )
909 theFillAsp->SetEdgeOff ();
910 //else
911 // theFillAsp->SetEdgeOn ();
912
913 if( anIntColor!=aBackColor )
914 theFillAsp->SetDistinguishOn();
915 else
916 theFillAsp->SetDistinguishOff();
917
918 if( IsFacePolygons )
919 {
920 aGroup->SetPrimitivesAspect ( theFillAsp );
921 aGroup->BeginPrimitives ();
922 aGroup->AddPrimitiveArray ( thePolygons );
923 aGroup->EndPrimitives ();
924 }
925
926 if( IsVolumePolygons )
927 {
928 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
929 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
930
931 Standard_Boolean isSupressBackFaces = Standard_False;
932 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
933 if (!aDrawer.IsNull())
934 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
935
936 if (isSupressBackFaces)
937 aCullFillAsp->SuppressBackFace();
938
939 aGroup->SetPrimitivesAspect ( aCullFillAsp );
940 aGroup->BeginPrimitives ();
941 aGroup->AddPrimitiveArray ( theVolumesInShad );
942 aGroup->EndPrimitives ();
943 }
944 }
945
946 if ( IsPolylines && !IsPolygonsEdgesOff )
947 {
948 Prs3d_Root::NewGroup ( Prs );
949 Handle (Graphic3d_Group) aLGroup = Prs3d_Root::CurrentGroup ( Prs );
950
951 theFillAsp->SetEdgeOff();
952 if ( IsSelected )
953 aLGroup->SetPrimitivesAspect ( theLineAsp );
954 else
955 {
956 aLGroup->SetPrimitivesAspect ( theFillAsp );
957 aLGroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d
958 ( anEdgeColor, Aspect_TOL_SOLID, aWidth ) );
959 }
960 aLGroup->BeginPrimitives ();
961 aLGroup->AddPrimitiveArray ( theLines );
962 aLGroup->EndPrimitives ();
963 theFillAsp->SetEdgeOn();
964 }
965
966 if ( IsLinkPolylines )
967 {
968 Prs3d_Root::NewGroup ( Prs );
969 Handle (Graphic3d_Group) aBeamGroup = Prs3d_Root::CurrentGroup ( Prs );
970
971 theFillAsp->SetEdgeOff();
972 if ( !IsSelected )
973 aBeamGroup->SetPrimitivesAspect ( theFillAsp );
974 aBeamGroup->SetPrimitivesAspect ( theLineAsp );
975
976 aBeamGroup->BeginPrimitives();
977 aBeamGroup->AddPrimitiveArray ( theLinkLines );
978 aBeamGroup->EndPrimitives();
979 theFillAsp->SetEdgeOn();
980 }
981
982 if ( IsPolygons && theFillAsp->FrontMaterial().Transparency()>=0.01 )
983 {
984 Prs3d_Root::NewGroup ( Prs );
985 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup ( Prs );
986
987 //if ( IsPolygonsEdgesOff )
988 theFillAsp->SetEdgeOff ();
989 //else
990 // theFillAsp->SetEdgeOn ();
991
992 if( anIntColor!=aBackColor )
993 theFillAsp->SetDistinguishOn();
994 else
995 theFillAsp->SetDistinguishOff();
996
997 if( IsFacePolygons )
998 {
999 aGroup->SetPrimitivesAspect ( theFillAsp );
1000 aGroup->BeginPrimitives ();
1001 aGroup->AddPrimitiveArray ( thePolygons );
1002 aGroup->EndPrimitives ();
1003 }
1004
1005 if( IsVolumePolygons )
1006 {
1007 Handle( Graphic3d_AspectFillArea3d ) aCullFillAsp =
1008 new Graphic3d_AspectFillArea3d( *( theFillAsp.operator->() ) );
1009
1010 Standard_Boolean isSupressBackFaces = Standard_False;
1011 Handle( MeshVS_Drawer ) aDrawer = GetDrawer();
1012 if (!aDrawer.IsNull())
1013 aDrawer->GetBoolean ( MeshVS_DA_SupressBackFaces, isSupressBackFaces );
1014
1015 if (isSupressBackFaces)
1016 aCullFillAsp->SuppressBackFace();
1017
1018 aGroup->SetPrimitivesAspect ( aCullFillAsp );
1019 aGroup->BeginPrimitives ();
1020 aGroup->AddPrimitiveArray ( theVolumesInShad );
1021 aGroup->EndPrimitives ();
1022 }
1023 }
1024}
1025
1026//================================================================
1027// Function : CalculateCenter
1028// Purpose :
1029//================================================================
1030void MeshVS_MeshPrsBuilder::CalculateCenter (const TColStd_Array1OfReal& theCoords,
1031 const Standard_Integer NbNodes,
1032 Standard_Real &xG,
1033 Standard_Real &yG,
1034 Standard_Real &zG)
1035{
1036 xG = yG = zG = 0;
1037 if ( NbNodes < 4 )
1038 {
1039 for ( Standard_Integer k=1; k<=NbNodes; k++)
1040 {
1041 xG += theCoords(3*k-2);
1042 yG += theCoords(3*k-1);
1043 zG += theCoords(3*k);
1044 }
1045 xG /= Standard_Real(NbNodes);
1046 yG /= Standard_Real(NbNodes);
1047 zG /= Standard_Real(NbNodes);
1048 }
1049 else
1050 {
1051 Standard_Integer a = 1, b = 3;
1052 xG = ( theCoords( 3*a-2 ) + theCoords( 3*b-2 ) ) / 2.0;
1053 yG = ( theCoords( 3*a-1 ) + theCoords( 3*b-1 ) ) / 2.0;
1054 zG = ( theCoords( 3*a ) + theCoords( 3*b ) ) / 2.0;
1055 }
1056}